 Chromium Code Reviews
 Chromium Code Reviews Issue 10701054:
  Enable stub generation using Hydrogen/Lithium (again)  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 10701054:
  Enable stub generation using Hydrogen/Lithium (again)  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| OLD | NEW | 
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright | 
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. | 
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above | 
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following | 
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided | 
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
| 27 | 27 | 
| 28 #include "v8.h" | 28 #include "v8.h" | 
| 29 | 29 | 
| 30 #include "bootstrapper.h" | 30 #include "bootstrapper.h" | 
| 31 #include "code-stubs.h" | 31 #include "code-stubs.h" | 
| 32 #include "stub-cache.h" | 32 #include "stub-cache.h" | 
| 33 #include "factory.h" | 33 #include "factory.h" | 
| 34 #include "gdb-jit.h" | 34 #include "gdb-jit.h" | 
| 35 #include "hydrogen.h" | |
| 36 #include "lithium.h" | |
| 35 #include "macro-assembler.h" | 37 #include "macro-assembler.h" | 
| 36 | 38 | 
| 37 namespace v8 { | 39 namespace v8 { | 
| 38 namespace internal { | 40 namespace internal { | 
| 39 | 41 | 
| 40 bool CodeStub::FindCodeInCache(Code** code_out) { | 42 bool CodeStub::FindCodeInCache(Code** code_out) { | 
| 41 Heap* heap = Isolate::Current()->heap(); | 43 Heap* heap = Isolate::Current()->heap(); | 
| 42 int index = heap->code_stubs()->FindEntry(GetKey()); | 44 int index = heap->code_stubs()->FindEntry(GetKey()); | 
| 43 if (index != UnseededNumberDictionary::kNotFound) { | 45 if (index != UnseededNumberDictionary::kNotFound) { | 
| 44 *code_out = Code::cast(heap->code_stubs()->ValueAt(index)); | 46 *code_out = Code::cast(heap->code_stubs()->ValueAt(index)); | 
| 45 return true; | 47 return true; | 
| 46 } | 48 } | 
| 47 return false; | 49 return false; | 
| 48 } | 50 } | 
| 49 | 51 | 
| 50 | 52 | 
| 51 void CodeStub::GenerateCode(MacroAssembler* masm) { | 53 Handle<Code> HydrogenCodeStub::GenerateCode() { | 
| 52 // Update the static counter each time a new code stub is generated. | 54 Isolate* isolate = Isolate::Current(); | 
| 53 masm->isolate()->counters()->code_stubs()->Increment(); | 55 CompilationInfoWithZone info(isolate); | 
| 54 | 56 if (FLAG_trace_hydrogen) { | 
| 55 // Nested stubs are not allowed for leaves. | 57 PrintF("-----------------------------------------------------------\n"); | 
| 56 AllowStubCallsScope allow_scope(masm, false); | 58 PrintF("Compiling stub using hydrogen\n"); | 
| 57 | 59 HTracer::Instance()->TraceCompilation(&info); | 
| 58 // Generate the code for the stub. | 60 } | 
| 59 masm->set_generating_stub(true); | 61 HGraph graph(&info); | 
| 60 NoCurrentFrameScope scope(masm); | 62 Generate(&graph); | 
| 61 Generate(masm); | 63 graph.OrderBlocks(); | 
| 64 graph.AssignDominators(); | |
| 65 graph.CollectPhis(); | |
| 66 graph.InsertRepresentationChanges(); | |
| 67 graph.EliminateRedundantBoundsChecks(); | |
| 68 LChunk* chunk = LChunk::NewChunk(&graph); | |
| 69 ASSERT(chunk != NULL); | |
| 70 Handle<Code> stub = chunk->Codegen(Code::COMPILED_STUB); | |
| 71 stub->Print(); | |
| 
Jakob Kummerow
2012/11/19 12:36:00
Don't forget to remove this (or surround with "if
 
danno
2012/11/26 17:16:18
Done.
 | |
| 72 return stub; | |
| 62 } | 73 } | 
| 63 | 74 | 
| 64 | 75 | 
| 76 void KeyedLoadFastElementStub::Generate(HGraph* graph) { | |
| 77 Zone* zone = graph->zone(); | |
| 78 HInstruction* receiver = new(zone) HParameter(0, KEYED_LOAD_IC_PARAMETER); | |
| 79 graph->entry_block()->AddInstruction(receiver); | |
| 80 graph->start_environment()->Push(receiver); | |
| 81 HInstruction* key = new(zone) HParameter(1, KEYED_LOAD_IC_PARAMETER); | |
| 82 graph->entry_block()->AddInstruction(key); | |
| 83 graph->start_environment()->Push(key); | |
| 84 | |
| 85 graph->entry_block()->AddSimulate(BailoutId::StubEntry()); | |
| 86 | |
| 87 HBasicBlock* next_block = graph->CreateBasicBlock(); | |
| 88 next_block->SetInitialEnvironment(graph->start_environment()); | |
| 89 HGoto* jump = new(zone) HGoto(next_block); | |
| 90 graph->entry_block()->Finish(jump); | |
| 91 | |
| 92 HInstruction* load = HGraphBuilder::BuildUncheckedMonomorphicElementAccess( | |
| 93 graph, | |
| 94 next_block, receiver, key, NULL, NULL, | |
| 95 is_js_array(), elements_kind(), false, zone); | |
| 96 next_block->AddInstruction(load); | |
| 97 | |
| 98 HReturn* ret = new(zone) HReturn(load); | |
| 99 next_block->Finish(ret); | |
| 100 } | |
| 101 | |
| 102 | |
| 65 SmartArrayPointer<const char> CodeStub::GetName() { | 103 SmartArrayPointer<const char> CodeStub::GetName() { | 
| 66 char buffer[100]; | 104 char buffer[100]; | 
| 67 NoAllocationStringAllocator allocator(buffer, | 105 NoAllocationStringAllocator allocator(buffer, | 
| 68 static_cast<unsigned>(sizeof(buffer))); | 106 static_cast<unsigned>(sizeof(buffer))); | 
| 69 StringStream stream(&allocator); | 107 StringStream stream(&allocator); | 
| 70 PrintName(&stream); | 108 PrintName(&stream); | 
| 71 return stream.ToCString(); | 109 return stream.ToCString(); | 
| 72 } | 110 } | 
| 73 | 111 | 
| 74 | 112 | 
| 75 void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) { | 113 void CodeStub::RecordCodeGeneration(Code* code, Isolate* isolate) { | 
| 76 Isolate* isolate = masm->isolate(); | |
| 77 SmartArrayPointer<const char> name = GetName(); | 114 SmartArrayPointer<const char> name = GetName(); | 
| 78 PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name)); | 115 PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name)); | 
| 79 GDBJIT(AddCode(GDBJITInterface::STUB, *name, code)); | 116 GDBJIT(AddCode(GDBJITInterface::STUB, *name, code)); | 
| 80 Counters* counters = isolate->counters(); | 117 Counters* counters = isolate->counters(); | 
| 81 counters->total_stubs_code_size()->Increment(code->instruction_size()); | 118 counters->total_stubs_code_size()->Increment(code->instruction_size()); | 
| 82 } | 119 } | 
| 83 | 120 | 
| 84 | 121 | 
| 85 int CodeStub::GetCodeKind() { | 122 int CodeStub::GetCodeKind() { | 
| 86 return Code::STUB; | 123 return Code::STUB; | 
| 87 } | 124 } | 
| 88 | 125 | 
| 89 | 126 | 
| 127 Handle<Code> PlatformCodeStub::GenerateCode() { | |
| 128 Isolate* isolate = Isolate::Current(); | |
| 129 Factory* factory = isolate->factory(); | |
| 130 | |
| 131 // Generate the new code. | |
| 132 MacroAssembler masm(isolate, NULL, 256); | |
| 133 | |
| 134 { | |
| 135 // Update the static counter each time a new code stub is generated. | |
| 136 isolate->counters()->code_stubs()->Increment(); | |
| 137 | |
| 138 // Nested stubs are not allowed for leaves. | |
| 139 AllowStubCallsScope allow_scope(&masm, false); | |
| 140 | |
| 141 // Generate the code for the stub. | |
| 142 masm.set_generating_stub(true); | |
| 143 NoCurrentFrameScope scope(&masm); | |
| 144 Generate(&masm); | |
| 145 } | |
| 146 | |
| 147 // Create the code object. | |
| 148 CodeDesc desc; | |
| 149 masm.GetCode(&desc); | |
| 150 | |
| 151 // Copy the generated code into a heap object. | |
| 152 Code::Flags flags = Code::ComputeFlags( | |
| 153 static_cast<Code::Kind>(GetCodeKind()), | |
| 154 GetICState()); | |
| 155 Handle<Code> new_object = factory->NewCode( | |
| 156 desc, flags, masm.CodeObject(), NeedsImmovableCode()); | |
| 157 return new_object; | |
| 158 } | |
| 159 | |
| 160 | |
| 90 Handle<Code> CodeStub::GetCode() { | 161 Handle<Code> CodeStub::GetCode() { | 
| 91 Isolate* isolate = Isolate::Current(); | 162 Isolate* isolate = Isolate::Current(); | 
| 92 Factory* factory = isolate->factory(); | 163 Factory* factory = isolate->factory(); | 
| 93 Heap* heap = isolate->heap(); | 164 Heap* heap = isolate->heap(); | 
| 94 Code* code; | 165 Code* code; | 
| 95 if (UseSpecialCache() | 166 if (UseSpecialCache() | 
| 96 ? FindCodeInSpecialCache(&code) | 167 ? FindCodeInSpecialCache(&code) | 
| 97 : FindCodeInCache(&code)) { | 168 : FindCodeInCache(&code)) { | 
| 98 ASSERT(IsPregenerated() == code->is_pregenerated()); | 169 ASSERT(IsPregenerated() == code->is_pregenerated()); | 
| 99 return Handle<Code>(code); | 170 return Handle<Code>(code); | 
| 100 } | 171 } | 
| 101 | 172 | 
| 102 { | 173 { | 
| 103 HandleScope scope(isolate); | 174 HandleScope scope(isolate); | 
| 104 | 175 | 
| 105 // Generate the new code. | 176 Handle<Code> new_object = GenerateCode(); | 
| 106 MacroAssembler masm(isolate, NULL, 256); | |
| 107 GenerateCode(&masm); | |
| 108 | |
| 109 // Create the code object. | |
| 110 CodeDesc desc; | |
| 111 masm.GetCode(&desc); | |
| 112 | |
| 113 // Copy the generated code into a heap object. | |
| 114 Code::Flags flags = Code::ComputeFlags( | |
| 115 static_cast<Code::Kind>(GetCodeKind()), | |
| 116 GetICState()); | |
| 117 Handle<Code> new_object = factory->NewCode( | |
| 118 desc, flags, masm.CodeObject(), NeedsImmovableCode()); | |
| 119 new_object->set_major_key(MajorKey()); | 177 new_object->set_major_key(MajorKey()); | 
| 120 FinishCode(new_object); | 178 FinishCode(new_object); | 
| 121 RecordCodeGeneration(*new_object, &masm); | 179 RecordCodeGeneration(*new_object, isolate); | 
| 122 | 180 | 
| 123 #ifdef ENABLE_DISASSEMBLER | 181 #ifdef ENABLE_DISASSEMBLER | 
| 124 if (FLAG_print_code_stubs) { | 182 if (FLAG_print_code_stubs) { | 
| 125 new_object->Disassemble(*GetName()); | 183 new_object->Disassemble(*GetName()); | 
| 126 PrintF("\n"); | 184 PrintF("\n"); | 
| 127 } | 185 } | 
| 128 #endif | 186 #endif | 
| 129 | 187 | 
| 130 if (UseSpecialCache()) { | 188 if (UseSpecialCache()) { | 
| 131 AddToSpecialCache(new_object); | 189 AddToSpecialCache(new_object); | 
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 return_true_false_object = "_TRUEFALSE"; | 312 return_true_false_object = "_TRUEFALSE"; | 
| 255 } | 313 } | 
| 256 | 314 | 
| 257 stream->Add("InstanceofStub%s%s%s", | 315 stream->Add("InstanceofStub%s%s%s", | 
| 258 args, | 316 args, | 
| 259 inline_check, | 317 inline_check, | 
| 260 return_true_false_object); | 318 return_true_false_object); | 
| 261 } | 319 } | 
| 262 | 320 | 
| 263 | 321 | 
| 264 void JSEntryStub::FinishCode(Handle<Code> code) { | 322 void JSEntryStub:: | 
| 323 FinishCode(Handle<Code> code) { | |
| 265 Handle<FixedArray> handler_table = | 324 Handle<FixedArray> handler_table = | 
| 266 code->GetIsolate()->factory()->NewFixedArray(1, TENURED); | 325 code->GetIsolate()->factory()->NewFixedArray(1, TENURED); | 
| 267 handler_table->set(0, Smi::FromInt(handler_offset_)); | 326 handler_table->set(0, Smi::FromInt(handler_offset_)); | 
| 268 code->set_handler_table(*handler_table); | 327 code->set_handler_table(*handler_table); | 
| 269 } | 328 } | 
| 270 | 329 | 
| 271 | 330 | 
| 272 void KeyedLoadElementStub::Generate(MacroAssembler* masm) { | 331 void KeyedLoadDictionaryElementStub::Generate(MacroAssembler* masm) { | 
| 273 switch (elements_kind_) { | 332 KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm); | 
| 274 case FAST_ELEMENTS: | |
| 275 case FAST_HOLEY_ELEMENTS: | |
| 276 case FAST_SMI_ELEMENTS: | |
| 277 case FAST_HOLEY_SMI_ELEMENTS: | |
| 278 KeyedLoadStubCompiler::GenerateLoadFastElement(masm); | |
| 279 break; | |
| 280 case FAST_DOUBLE_ELEMENTS: | |
| 281 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
| 282 KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(masm); | |
| 283 break; | |
| 284 case EXTERNAL_BYTE_ELEMENTS: | |
| 285 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 286 case EXTERNAL_SHORT_ELEMENTS: | |
| 287 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 288 case EXTERNAL_INT_ELEMENTS: | |
| 289 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 290 case EXTERNAL_FLOAT_ELEMENTS: | |
| 291 case EXTERNAL_DOUBLE_ELEMENTS: | |
| 292 case EXTERNAL_PIXEL_ELEMENTS: | |
| 293 KeyedLoadStubCompiler::GenerateLoadExternalArray(masm, elements_kind_); | |
| 294 break; | |
| 295 case DICTIONARY_ELEMENTS: | |
| 296 KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm); | |
| 297 break; | |
| 298 case NON_STRICT_ARGUMENTS_ELEMENTS: | |
| 299 UNREACHABLE(); | |
| 300 break; | |
| 301 } | |
| 302 } | 333 } | 
| 303 | 334 | 
| 304 | 335 | 
| 305 void KeyedStoreElementStub::Generate(MacroAssembler* masm) { | 336 void KeyedStoreElementStub::Generate(MacroAssembler* masm) { | 
| 306 switch (elements_kind_) { | 337 switch (elements_kind_) { | 
| 307 case FAST_ELEMENTS: | 338 case FAST_ELEMENTS: | 
| 308 case FAST_HOLEY_ELEMENTS: | 339 case FAST_HOLEY_ELEMENTS: | 
| 309 case FAST_SMI_ELEMENTS: | 340 case FAST_SMI_ELEMENTS: | 
| 310 case FAST_HOLEY_SMI_ELEMENTS: { | 341 case FAST_HOLEY_SMI_ELEMENTS: { | 
| 311 KeyedStoreStubCompiler::GenerateStoreFastElement(masm, | 342 KeyedStoreStubCompiler::GenerateStoreFastElement(masm, | 
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 // already active, as the hooks won't stack. | 527 // already active, as the hooks won't stack. | 
| 497 if (entry_hook != 0 && entry_hook_ != 0) | 528 if (entry_hook != 0 && entry_hook_ != 0) | 
| 498 return false; | 529 return false; | 
| 499 | 530 | 
| 500 entry_hook_ = entry_hook; | 531 entry_hook_ = entry_hook; | 
| 501 return true; | 532 return true; | 
| 502 } | 533 } | 
| 503 | 534 | 
| 504 | 535 | 
| 505 } } // namespace v8::internal | 536 } } // namespace v8::internal | 
| OLD | NEW |