blob: dbc39ff3bf9df246e6c0ae4a881ca0fea3ccdb9f [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "bootstrapper.h"
31#include "code-stubs.h"
32#include "factory.h"
33#include "macro-assembler.h"
34
35namespace v8 {
36namespace internal {
37
38Handle<Code> CodeStub::GetCode() {
Steve Blockd0582a62009-12-15 09:54:21 +000039 bool custom_cache = has_custom_cache();
40
41 int index = 0;
42 uint32_t key = 0;
43 if (custom_cache) {
44 Code* cached;
45 if (GetCustomCache(&cached)) {
46 return Handle<Code>(cached);
47 } else {
48 index = NumberDictionary::kNotFound;
49 }
50 } else {
51 key = GetKey();
52 index = Heap::code_stubs()->FindEntry(key);
53 if (index != NumberDictionary::kNotFound)
54 return Handle<Code>(Code::cast(Heap::code_stubs()->ValueAt(index)));
55 }
56
57 Code* result;
58 {
59 v8::HandleScope scope;
Steve Blocka7e24c12009-10-30 11:49:00 +000060
61 // Update the static counter each time a new code stub is generated.
62 Counters::code_stubs.Increment();
63
64 // Generate the new code.
65 MacroAssembler masm(NULL, 256);
66
67 // Nested stubs are not allowed for leafs.
68 masm.set_allow_stub_calls(AllowsStubCalls());
69
70 // Generate the code for the stub.
71 masm.set_generating_stub(true);
72 Generate(&masm);
73
74 // Create the code object.
75 CodeDesc desc;
76 masm.GetCode(&desc);
77
78 // Copy the generated code into a heap object, and store the major key.
79 Code::Flags flags = Code::ComputeFlags(Code::STUB, InLoop());
80 Handle<Code> code = Factory::NewCode(desc, NULL, flags, masm.CodeObject());
81 code->set_major_key(MajorKey());
82
83 // Add unresolved entries in the code to the fixup list.
84 Bootstrapper::AddFixup(*code, &masm);
85
86 LOG(CodeCreateEvent(Logger::STUB_TAG, *code, GetName()));
87 Counters::total_stubs_code_size.Increment(code->instruction_size());
88
89#ifdef ENABLE_DISASSEMBLER
90 if (FLAG_print_code_stubs) {
91#ifdef DEBUG
92 Print();
93#endif
94 code->Disassemble(GetName());
95 PrintF("\n");
96 }
97#endif
98
Steve Blockd0582a62009-12-15 09:54:21 +000099 if (custom_cache) {
100 SetCustomCache(*code);
101 } else {
102 // Update the dictionary and the root in Heap.
103 Handle<NumberDictionary> dict =
104 Factory::DictionaryAtNumberPut(
105 Handle<NumberDictionary>(Heap::code_stubs()),
106 key,
107 code);
108 Heap::public_set_code_stubs(*dict);
109 }
110 result = *code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000111 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000112
Steve Blockd0582a62009-12-15 09:54:21 +0000113 return Handle<Code>(result);
Steve Blocka7e24c12009-10-30 11:49:00 +0000114}
115
116
117const char* CodeStub::MajorName(CodeStub::Major major_key) {
118 switch (major_key) {
Steve Blockd0582a62009-12-15 09:54:21 +0000119#define DEF_CASE(name) case name: return #name;
120 CODE_STUB_LIST(DEF_CASE)
121#undef DEF_CASE
Steve Blocka7e24c12009-10-30 11:49:00 +0000122 default:
123 UNREACHABLE();
124 return NULL;
125 }
126}
127
128
129} } // namespace v8::internal