• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 "gdb-jit.h"
34 #include "macro-assembler.h"
35 
36 namespace v8 {
37 namespace internal {
38 
FindCodeInCache(Code ** code_out)39 bool CodeStub::FindCodeInCache(Code** code_out) {
40   Heap* heap = Isolate::Current()->heap();
41   int index = heap->code_stubs()->FindEntry(GetKey());
42   if (index != NumberDictionary::kNotFound) {
43     *code_out = Code::cast(heap->code_stubs()->ValueAt(index));
44     return true;
45   }
46   return false;
47 }
48 
49 
GenerateCode(MacroAssembler * masm)50 void CodeStub::GenerateCode(MacroAssembler* masm) {
51   // Update the static counter each time a new code stub is generated.
52   masm->isolate()->counters()->code_stubs()->Increment();
53 
54   // Nested stubs are not allowed for leafs.
55   AllowStubCallsScope allow_scope(masm, AllowsStubCalls());
56 
57   // Generate the code for the stub.
58   masm->set_generating_stub(true);
59   Generate(masm);
60 }
61 
62 
RecordCodeGeneration(Code * code,MacroAssembler * masm)63 void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
64   code->set_major_key(MajorKey());
65 
66   Isolate* isolate = masm->isolate();
67   PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
68   GDBJIT(AddCode(GDBJITInterface::STUB, GetName(), code));
69   Counters* counters = isolate->counters();
70   counters->total_stubs_code_size()->Increment(code->instruction_size());
71 
72 #ifdef ENABLE_DISASSEMBLER
73   if (FLAG_print_code_stubs) {
74 #ifdef DEBUG
75     Print();
76 #endif
77     code->Disassemble(GetName());
78     PrintF("\n");
79   }
80 #endif
81 }
82 
83 
GetCodeKind()84 int CodeStub::GetCodeKind() {
85   return Code::STUB;
86 }
87 
88 
GetCode()89 Handle<Code> CodeStub::GetCode() {
90   Isolate* isolate = Isolate::Current();
91   Factory* factory = isolate->factory();
92   Heap* heap = isolate->heap();
93   Code* code;
94   if (!FindCodeInCache(&code)) {
95     HandleScope scope(isolate);
96 
97     // Generate the new code.
98     MacroAssembler masm(isolate, NULL, 256);
99     GenerateCode(&masm);
100 
101     // Create the code object.
102     CodeDesc desc;
103     masm.GetCode(&desc);
104 
105     // Copy the generated code into a heap object.
106     Code::Flags flags = Code::ComputeFlags(
107         static_cast<Code::Kind>(GetCodeKind()),
108         InLoop(),
109         GetICState());
110     Handle<Code> new_object = factory->NewCode(
111         desc, flags, masm.CodeObject(), NeedsImmovableCode());
112     RecordCodeGeneration(*new_object, &masm);
113     FinishCode(*new_object);
114 
115     // Update the dictionary and the root in Heap.
116     Handle<NumberDictionary> dict =
117         factory->DictionaryAtNumberPut(
118             Handle<NumberDictionary>(heap->code_stubs()),
119             GetKey(),
120             new_object);
121     heap->public_set_code_stubs(*dict);
122 
123     code = *new_object;
124   }
125 
126   ASSERT(!NeedsImmovableCode() || heap->lo_space()->Contains(code));
127   return Handle<Code>(code, isolate);
128 }
129 
130 
TryGetCode()131 MaybeObject* CodeStub::TryGetCode() {
132   Code* code;
133   if (!FindCodeInCache(&code)) {
134     // Generate the new code.
135     MacroAssembler masm(Isolate::Current(), NULL, 256);
136     GenerateCode(&masm);
137     Heap* heap = masm.isolate()->heap();
138 
139     // Create the code object.
140     CodeDesc desc;
141     masm.GetCode(&desc);
142 
143     // Try to copy the generated code into a heap object.
144     Code::Flags flags = Code::ComputeFlags(
145         static_cast<Code::Kind>(GetCodeKind()),
146         InLoop(),
147         GetICState());
148     Object* new_object;
149     { MaybeObject* maybe_new_object =
150           heap->CreateCode(desc, flags, masm.CodeObject());
151       if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
152     }
153     code = Code::cast(new_object);
154     RecordCodeGeneration(code, &masm);
155     FinishCode(code);
156 
157     // Try to update the code cache but do not fail if unable.
158     MaybeObject* maybe_new_object =
159         heap->code_stubs()->AtNumberPut(GetKey(), code);
160     if (maybe_new_object->ToObject(&new_object)) {
161       heap->public_set_code_stubs(NumberDictionary::cast(new_object));
162     }
163   }
164 
165   return code;
166 }
167 
168 
MajorName(CodeStub::Major major_key,bool allow_unknown_keys)169 const char* CodeStub::MajorName(CodeStub::Major major_key,
170                                 bool allow_unknown_keys) {
171   switch (major_key) {
172 #define DEF_CASE(name) case name: return #name;
173     CODE_STUB_LIST(DEF_CASE)
174 #undef DEF_CASE
175     default:
176       if (!allow_unknown_keys) {
177         UNREACHABLE();
178       }
179       return NULL;
180   }
181 }
182 
183 
MinorKey()184 int ICCompareStub::MinorKey() {
185   return OpField::encode(op_ - Token::EQ) | StateField::encode(state_);
186 }
187 
188 
Generate(MacroAssembler * masm)189 void ICCompareStub::Generate(MacroAssembler* masm) {
190   switch (state_) {
191     case CompareIC::UNINITIALIZED:
192       GenerateMiss(masm);
193       break;
194     case CompareIC::SMIS:
195       GenerateSmis(masm);
196       break;
197     case CompareIC::HEAP_NUMBERS:
198       GenerateHeapNumbers(masm);
199       break;
200     case CompareIC::OBJECTS:
201       GenerateObjects(masm);
202       break;
203     default:
204       UNREACHABLE();
205   }
206 }
207 
208 
GetName()209 const char* InstanceofStub::GetName() {
210   if (name_ != NULL) return name_;
211   const int kMaxNameLength = 100;
212   name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
213       kMaxNameLength);
214   if (name_ == NULL) return "OOM";
215 
216   const char* args = "";
217   if (HasArgsInRegisters()) {
218     args = "_REGS";
219   }
220 
221   const char* inline_check = "";
222   if (HasCallSiteInlineCheck()) {
223     inline_check = "_INLINE";
224   }
225 
226   const char* return_true_false_object = "";
227   if (ReturnTrueFalseObject()) {
228     return_true_false_object = "_TRUEFALSE";
229   }
230 
231   OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
232                "InstanceofStub%s%s%s",
233                args,
234                inline_check,
235                return_true_false_object);
236   return name_;
237 }
238 
239 
240 } }  // namespace v8::internal
241