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 11 matching lines...) Expand all Loading... |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
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 "cpu-profiler.h" |
32 #include "stub-cache.h" | 33 #include "stub-cache.h" |
33 #include "factory.h" | 34 #include "factory.h" |
34 #include "gdb-jit.h" | 35 #include "gdb-jit.h" |
35 #include "macro-assembler.h" | 36 #include "macro-assembler.h" |
36 | 37 |
37 namespace v8 { | 38 namespace v8 { |
38 namespace internal { | 39 namespace internal { |
39 | 40 |
40 | 41 |
41 CodeStubInterfaceDescriptor::CodeStubInterfaceDescriptor() | 42 CodeStubInterfaceDescriptor::CodeStubInterfaceDescriptor() |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 Counters* counters = isolate->counters(); | 78 Counters* counters = isolate->counters(); |
78 counters->total_stubs_code_size()->Increment(code->instruction_size()); | 79 counters->total_stubs_code_size()->Increment(code->instruction_size()); |
79 } | 80 } |
80 | 81 |
81 | 82 |
82 Code::Kind CodeStub::GetCodeKind() const { | 83 Code::Kind CodeStub::GetCodeKind() const { |
83 return Code::STUB; | 84 return Code::STUB; |
84 } | 85 } |
85 | 86 |
86 | 87 |
| 88 Handle<Code> CodeStub::GetCodeCopyFromTemplate(Isolate* isolate) { |
| 89 Handle<Code> ic = GetCode(isolate); |
| 90 ic = isolate->factory()->CopyCode(ic); |
| 91 RecordCodeGeneration(*ic, isolate); |
| 92 return ic; |
| 93 } |
| 94 |
| 95 |
87 Handle<Code> PlatformCodeStub::GenerateCode() { | 96 Handle<Code> PlatformCodeStub::GenerateCode() { |
88 Isolate* isolate = Isolate::Current(); | 97 Isolate* isolate = Isolate::Current(); |
89 Factory* factory = isolate->factory(); | 98 Factory* factory = isolate->factory(); |
90 | 99 |
91 // Generate the new code. | 100 // Generate the new code. |
92 MacroAssembler masm(isolate, NULL, 256); | 101 MacroAssembler masm(isolate, NULL, 256); |
93 | 102 |
94 { | 103 { |
95 // Update the static counter each time a new code stub is generated. | 104 // Update the static counter each time a new code stub is generated. |
96 isolate->counters()->code_stubs()->Increment(); | 105 isolate->counters()->code_stubs()->Increment(); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 #undef DEF_CASE | 186 #undef DEF_CASE |
178 default: | 187 default: |
179 if (!allow_unknown_keys) { | 188 if (!allow_unknown_keys) { |
180 UNREACHABLE(); | 189 UNREACHABLE(); |
181 } | 190 } |
182 return NULL; | 191 return NULL; |
183 } | 192 } |
184 } | 193 } |
185 | 194 |
186 | 195 |
| 196 void CodeStub::PrintBaseName(StringStream* stream) { |
| 197 stream->Add("%s", MajorName(MajorKey(), false)); |
| 198 } |
| 199 |
| 200 |
187 void CodeStub::PrintName(StringStream* stream) { | 201 void CodeStub::PrintName(StringStream* stream) { |
188 stream->Add("%s", MajorName(MajorKey(), false)); | 202 PrintBaseName(stream); |
| 203 PrintState(stream); |
| 204 } |
| 205 |
| 206 |
| 207 Builtins::JavaScript UnaryOpStub::ToJSBuiltin() { |
| 208 switch (operation_) { |
| 209 default: |
| 210 UNREACHABLE(); |
| 211 case Token::SUB: |
| 212 return Builtins::UNARY_MINUS; |
| 213 case Token::BIT_NOT: |
| 214 return Builtins::BIT_NOT; |
| 215 } |
| 216 } |
| 217 |
| 218 |
| 219 Handle<JSFunction> UnaryOpStub::ToJSFunction(Isolate* isolate) { |
| 220 Handle<JSBuiltinsObject> builtins(isolate->js_builtins_object()); |
| 221 Object* builtin = builtins->javascript_builtin(ToJSBuiltin()); |
| 222 return Handle<JSFunction>(JSFunction::cast(builtin), isolate); |
| 223 } |
| 224 |
| 225 |
| 226 MaybeObject* UnaryOpStub::Result(Handle<Object> object, Isolate* isolate) { |
| 227 Handle<JSFunction> builtin_function = ToJSFunction(isolate); |
| 228 bool caught_exception; |
| 229 Handle<Object> result = Execution::Call(builtin_function, object, |
| 230 0, NULL, &caught_exception); |
| 231 if (caught_exception) { |
| 232 return Failure::Exception(); |
| 233 } |
| 234 return *result; |
| 235 } |
| 236 |
| 237 |
| 238 void UnaryOpStub::UpdateStatus(Handle<Object> object) { |
| 239 State old_state(state_); |
| 240 if (object->IsSmi()) { |
| 241 state_.Add(SMI); |
| 242 if (operation_ == Token::SUB && *object == 0) { |
| 243 // The result (-0) has to be represented as double. |
| 244 state_.Add(HEAP_NUMBER); |
| 245 } |
| 246 } else if (object->IsHeapNumber()) { |
| 247 state_.Add(HEAP_NUMBER); |
| 248 } else { |
| 249 state_.Add(GENERIC); |
| 250 } |
| 251 TraceTransition(old_state, state_); |
| 252 } |
| 253 |
| 254 |
| 255 Handle<Type> UnaryOpStub::GetType(Isolate* isolate) { |
| 256 if (state_.Contains(GENERIC)) { |
| 257 return handle(Type::Any(), isolate); |
| 258 } |
| 259 Handle<Type> type = handle(Type::None(), isolate); |
| 260 if (state_.Contains(SMI)) { |
| 261 type = handle( |
| 262 Type::Union(type, handle(Type::Smi(), isolate)), isolate); |
| 263 } |
| 264 if (state_.Contains(HEAP_NUMBER)) { |
| 265 type = handle( |
| 266 Type::Union(type, handle(Type::Double(), isolate)), isolate); |
| 267 } |
| 268 return type; |
189 } | 269 } |
190 | 270 |
191 | 271 |
192 void BinaryOpStub::Generate(MacroAssembler* masm) { | 272 void BinaryOpStub::Generate(MacroAssembler* masm) { |
193 // Explicitly allow generation of nested stubs. It is safe here because | 273 // Explicitly allow generation of nested stubs. It is safe here because |
194 // generation code does not use any raw pointers. | 274 // generation code does not use any raw pointers. |
195 AllowStubCallsScope allow_stub_calls(masm, true); | 275 AllowStubCallsScope allow_stub_calls(masm, true); |
196 | 276 |
197 BinaryOpIC::TypeInfo operands_type = Max(left_type_, right_type_); | 277 BinaryOpIC::TypeInfo operands_type = Max(left_type_, right_type_); |
198 if (left_type_ == BinaryOpIC::ODDBALL && right_type_ == BinaryOpIC::ODDBALL) { | 278 if (left_type_ == BinaryOpIC::ODDBALL && right_type_ == BinaryOpIC::ODDBALL) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 break; | 347 break; |
268 default: | 348 default: |
269 UNREACHABLE(); | 349 UNREACHABLE(); |
270 } | 350 } |
271 } | 351 } |
272 | 352 |
273 | 353 |
274 #undef __ | 354 #undef __ |
275 | 355 |
276 | 356 |
| 357 void UnaryOpStub::PrintBaseName(StringStream* stream) { |
| 358 CodeStub::PrintBaseName(stream); |
| 359 if (operation_ == Token::SUB) stream->Add("Minus"); |
| 360 if (operation_ == Token::BIT_NOT) stream->Add("Not"); |
| 361 } |
| 362 |
| 363 |
| 364 void UnaryOpStub::PrintState(StringStream* stream) { |
| 365 state_.Print(stream); |
| 366 } |
| 367 |
| 368 |
| 369 void UnaryOpStub::State::Print(StringStream* stream) const { |
| 370 stream->Add("("); |
| 371 SimpleListPrinter printer(stream); |
| 372 if (IsEmpty()) printer.Add("None"); |
| 373 if (Contains(GENERIC)) printer.Add("Generic"); |
| 374 if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber"); |
| 375 if (Contains(SMI)) printer.Add("Smi"); |
| 376 stream->Add(")"); |
| 377 } |
| 378 |
| 379 |
277 void BinaryOpStub::PrintName(StringStream* stream) { | 380 void BinaryOpStub::PrintName(StringStream* stream) { |
278 const char* op_name = Token::Name(op_); | 381 const char* op_name = Token::Name(op_); |
279 const char* overwrite_name; | 382 const char* overwrite_name; |
280 switch (mode_) { | 383 switch (mode_) { |
281 case NO_OVERWRITE: overwrite_name = "Alloc"; break; | 384 case NO_OVERWRITE: overwrite_name = "Alloc"; break; |
282 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; | 385 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; |
283 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; | 386 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; |
284 default: overwrite_name = "UnknownOverwrite"; break; | 387 default: overwrite_name = "UnknownOverwrite"; break; |
285 } | 388 } |
286 stream->Add("BinaryOpStub_%s_%s_%s+%s", | 389 stream->Add("BinaryOpStub_%s_%s_%s+%s", |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 ASSERT(*known_map_ != NULL); | 526 ASSERT(*known_map_ != NULL); |
424 GenerateKnownObjects(masm); | 527 GenerateKnownObjects(masm); |
425 break; | 528 break; |
426 case CompareIC::GENERIC: | 529 case CompareIC::GENERIC: |
427 GenerateGeneric(masm); | 530 GenerateGeneric(masm); |
428 break; | 531 break; |
429 } | 532 } |
430 } | 533 } |
431 | 534 |
432 | 535 |
433 void CompareNilICStub::Record(Handle<Object> object) { | 536 void CompareNilICStub::UpdateStatus(Handle<Object> object) { |
434 ASSERT(state_ != State::Generic()); | 537 ASSERT(state_ != State::Generic()); |
| 538 State old_state(state_); |
435 if (object->IsNull()) { | 539 if (object->IsNull()) { |
436 state_.Add(NULL_TYPE); | 540 state_.Add(NULL_TYPE); |
437 } else if (object->IsUndefined()) { | 541 } else if (object->IsUndefined()) { |
438 state_.Add(UNDEFINED); | 542 state_.Add(UNDEFINED); |
439 } else if (object->IsUndetectableObject() || | 543 } else if (object->IsUndetectableObject() || |
440 object->IsOddball() || | 544 object->IsOddball() || |
441 !object->IsHeapObject()) { | 545 !object->IsHeapObject()) { |
442 state_ = State::Generic(); | 546 state_ = State::Generic(); |
443 } else if (IsMonomorphic()) { | 547 } else if (IsMonomorphic()) { |
444 state_ = State::Generic(); | 548 state_ = State::Generic(); |
445 } else { | 549 } else { |
446 state_.Add(MONOMORPHIC_MAP); | 550 state_.Add(MONOMORPHIC_MAP); |
447 } | 551 } |
| 552 TraceTransition(old_state, state_); |
448 } | 553 } |
449 | 554 |
450 | 555 |
451 void CompareNilICStub::State::TraceTransition(State to) const { | 556 template<class StateType> |
| 557 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { |
452 #ifdef DEBUG | 558 #ifdef DEBUG |
453 if (!FLAG_trace_ic) return; | 559 if (!FLAG_trace_ic) return; |
454 char buffer[100]; | 560 char buffer[100]; |
455 NoAllocationStringAllocator allocator(buffer, | 561 NoAllocationStringAllocator allocator(buffer, |
456 static_cast<unsigned>(sizeof(buffer))); | 562 static_cast<unsigned>(sizeof(buffer))); |
457 StringStream stream(&allocator); | 563 StringStream stream(&allocator); |
458 stream.Add("[CompareNilIC : "); | 564 stream.Add("["); |
459 Print(&stream); | 565 PrintBaseName(&stream); |
| 566 stream.Add(": "); |
| 567 from.Print(&stream); |
460 stream.Add("=>"); | 568 stream.Add("=>"); |
461 to.Print(&stream); | 569 to.Print(&stream); |
462 stream.Add("]\n"); | 570 stream.Add("]\n"); |
463 stream.OutputToStdOut(); | 571 stream.OutputToStdOut(); |
464 #endif | 572 #endif |
465 } | 573 } |
466 | 574 |
467 | 575 |
468 void CompareNilICStub::PrintName(StringStream* stream) { | 576 void CompareNilICStub::PrintBaseName(StringStream* stream) { |
469 stream->Add("CompareNilICStub_"); | 577 CodeStub::PrintBaseName(stream); |
470 state_.Print(stream); | 578 stream->Add((nil_value_ == kNullValue) ? "(NullValue)": |
471 stream->Add((nil_value_ == kNullValue) ? "(NullValue|": | 579 "(UndefinedValue)"); |
472 "(UndefinedValue|"); | |
473 } | 580 } |
474 | 581 |
475 | 582 |
| 583 void CompareNilICStub::PrintState(StringStream* stream) { |
| 584 state_.Print(stream); |
| 585 } |
| 586 |
| 587 |
476 void CompareNilICStub::State::Print(StringStream* stream) const { | 588 void CompareNilICStub::State::Print(StringStream* stream) const { |
477 stream->Add("("); | 589 stream->Add("("); |
478 SimpleListPrinter printer(stream); | 590 SimpleListPrinter printer(stream); |
479 if (IsEmpty()) printer.Add("None"); | 591 if (IsEmpty()) printer.Add("None"); |
480 if (Contains(UNDEFINED)) printer.Add("Undefined"); | 592 if (Contains(UNDEFINED)) printer.Add("Undefined"); |
481 if (Contains(NULL_TYPE)) printer.Add("Null"); | 593 if (Contains(NULL_TYPE)) printer.Add("Null"); |
482 if (Contains(MONOMORPHIC_MAP)) printer.Add("MonomorphicMap"); | 594 if (Contains(MONOMORPHIC_MAP)) printer.Add("MonomorphicMap"); |
483 if (Contains(UNDETECTABLE)) printer.Add("Undetectable"); | 595 if (Contains(UNDETECTABLE)) printer.Add("Undetectable"); |
484 if (Contains(GENERIC)) printer.Add("Generic"); | 596 if (Contains(GENERIC)) printer.Add("Generic"); |
485 stream->Add(")"); | 597 stream->Add(")"); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 handler_table->set(0, Smi::FromInt(handler_offset_)); | 656 handler_table->set(0, Smi::FromInt(handler_offset_)); |
545 code->set_handler_table(*handler_table); | 657 code->set_handler_table(*handler_table); |
546 } | 658 } |
547 | 659 |
548 | 660 |
549 void KeyedLoadDictionaryElementStub::Generate(MacroAssembler* masm) { | 661 void KeyedLoadDictionaryElementStub::Generate(MacroAssembler* masm) { |
550 KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm); | 662 KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm); |
551 } | 663 } |
552 | 664 |
553 | 665 |
| 666 void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) { |
| 667 CreateAllocationSiteStub stub; |
| 668 stub.GetCode(isolate)->set_is_pregenerated(true); |
| 669 } |
| 670 |
| 671 |
554 void KeyedStoreElementStub::Generate(MacroAssembler* masm) { | 672 void KeyedStoreElementStub::Generate(MacroAssembler* masm) { |
555 switch (elements_kind_) { | 673 switch (elements_kind_) { |
556 case FAST_ELEMENTS: | 674 case FAST_ELEMENTS: |
557 case FAST_HOLEY_ELEMENTS: | 675 case FAST_HOLEY_ELEMENTS: |
558 case FAST_SMI_ELEMENTS: | 676 case FAST_SMI_ELEMENTS: |
559 case FAST_HOLEY_SMI_ELEMENTS: { | 677 case FAST_HOLEY_SMI_ELEMENTS: { |
560 KeyedStoreStubCompiler::GenerateStoreFastElement(masm, | 678 KeyedStoreStubCompiler::GenerateStoreFastElement(masm, |
561 is_js_array_, | 679 is_js_array_, |
562 elements_kind_, | 680 elements_kind_, |
563 store_mode_); | 681 store_mode_); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 if (RecordCallTarget()) stream->Add("_Recording"); | 725 if (RecordCallTarget()) stream->Add("_Recording"); |
608 } | 726 } |
609 | 727 |
610 | 728 |
611 void CallConstructStub::PrintName(StringStream* stream) { | 729 void CallConstructStub::PrintName(StringStream* stream) { |
612 stream->Add("CallConstructStub"); | 730 stream->Add("CallConstructStub"); |
613 if (RecordCallTarget()) stream->Add("_Recording"); | 731 if (RecordCallTarget()) stream->Add("_Recording"); |
614 } | 732 } |
615 | 733 |
616 | 734 |
617 bool ToBooleanStub::Record(Handle<Object> object) { | 735 bool ToBooleanStub::UpdateStatus(Handle<Object> object) { |
618 Types old_types(types_); | 736 Types old_types(types_); |
619 bool to_boolean_value = types_.Record(object); | 737 bool to_boolean_value = types_.UpdateStatus(object); |
620 old_types.TraceTransition(types_); | 738 TraceTransition(old_types, types_); |
621 return to_boolean_value; | 739 return to_boolean_value; |
622 } | 740 } |
623 | 741 |
624 | 742 |
625 void ToBooleanStub::PrintName(StringStream* stream) { | 743 void ToBooleanStub::PrintState(StringStream* stream) { |
626 stream->Add("ToBooleanStub_"); | |
627 types_.Print(stream); | 744 types_.Print(stream); |
628 } | 745 } |
629 | 746 |
630 | 747 |
631 void ToBooleanStub::Types::Print(StringStream* stream) const { | 748 void ToBooleanStub::Types::Print(StringStream* stream) const { |
632 stream->Add("("); | 749 stream->Add("("); |
633 SimpleListPrinter printer(stream); | 750 SimpleListPrinter printer(stream); |
634 if (IsEmpty()) printer.Add("None"); | 751 if (IsEmpty()) printer.Add("None"); |
635 if (Contains(UNDEFINED)) printer.Add("Undefined"); | 752 if (Contains(UNDEFINED)) printer.Add("Undefined"); |
636 if (Contains(BOOLEAN)) printer.Add("Bool"); | 753 if (Contains(BOOLEAN)) printer.Add("Bool"); |
637 if (Contains(NULL_TYPE)) printer.Add("Null"); | 754 if (Contains(NULL_TYPE)) printer.Add("Null"); |
638 if (Contains(SMI)) printer.Add("Smi"); | 755 if (Contains(SMI)) printer.Add("Smi"); |
639 if (Contains(SPEC_OBJECT)) printer.Add("SpecObject"); | 756 if (Contains(SPEC_OBJECT)) printer.Add("SpecObject"); |
640 if (Contains(STRING)) printer.Add("String"); | 757 if (Contains(STRING)) printer.Add("String"); |
641 if (Contains(SYMBOL)) printer.Add("Symbol"); | 758 if (Contains(SYMBOL)) printer.Add("Symbol"); |
642 if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber"); | 759 if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber"); |
643 stream->Add(")"); | 760 stream->Add(")"); |
644 } | 761 } |
645 | 762 |
646 | 763 |
647 void ToBooleanStub::Types::TraceTransition(Types to) const { | 764 bool ToBooleanStub::Types::UpdateStatus(Handle<Object> object) { |
648 #ifdef DEBUG | |
649 if (!FLAG_trace_ic) return; | |
650 char buffer[100]; | |
651 NoAllocationStringAllocator allocator(buffer, | |
652 static_cast<unsigned>(sizeof(buffer))); | |
653 StringStream stream(&allocator); | |
654 stream.Add("[ToBooleanIC : "); | |
655 Print(&stream); | |
656 stream.Add("=>"); | |
657 to.Print(&stream); | |
658 stream.Add("]\n"); | |
659 stream.OutputToStdOut(); | |
660 #endif | |
661 } | |
662 | |
663 | |
664 bool ToBooleanStub::Types::Record(Handle<Object> object) { | |
665 if (object->IsUndefined()) { | 765 if (object->IsUndefined()) { |
666 Add(UNDEFINED); | 766 Add(UNDEFINED); |
667 return false; | 767 return false; |
668 } else if (object->IsBoolean()) { | 768 } else if (object->IsBoolean()) { |
669 Add(BOOLEAN); | 769 Add(BOOLEAN); |
670 return object->IsTrue(); | 770 return object->IsTrue(); |
671 } else if (object->IsNull()) { | 771 } else if (object->IsNull()) { |
672 Add(NULL_TYPE); | 772 Add(NULL_TYPE); |
673 return false; | 773 return false; |
674 } else if (object->IsSmi()) { | 774 } else if (object->IsSmi()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 | 806 |
707 | 807 |
708 bool ToBooleanStub::Types::CanBeUndetectable() const { | 808 bool ToBooleanStub::Types::CanBeUndetectable() const { |
709 return Contains(ToBooleanStub::SPEC_OBJECT) | 809 return Contains(ToBooleanStub::SPEC_OBJECT) |
710 || Contains(ToBooleanStub::STRING); | 810 || Contains(ToBooleanStub::STRING); |
711 } | 811 } |
712 | 812 |
713 | 813 |
714 void ElementsTransitionAndStoreStub::Generate(MacroAssembler* masm) { | 814 void ElementsTransitionAndStoreStub::Generate(MacroAssembler* masm) { |
715 Label fail; | 815 Label fail; |
716 AllocationSiteMode mode = AllocationSiteInfo::GetMode(from_, to_); | 816 AllocationSiteMode mode = AllocationSite::GetMode(from_, to_); |
717 ASSERT(!IsFastHoleyElementsKind(from_) || IsFastHoleyElementsKind(to_)); | 817 ASSERT(!IsFastHoleyElementsKind(from_) || IsFastHoleyElementsKind(to_)); |
718 if (!FLAG_trace_elements_transitions) { | 818 if (!FLAG_trace_elements_transitions) { |
719 if (IsFastSmiOrObjectElementsKind(to_)) { | 819 if (IsFastSmiOrObjectElementsKind(to_)) { |
720 if (IsFastSmiOrObjectElementsKind(from_)) { | 820 if (IsFastSmiOrObjectElementsKind(from_)) { |
721 ElementsTransitionGenerator:: | 821 ElementsTransitionGenerator:: |
722 GenerateMapChangeElementsTransition(masm, mode, &fail); | 822 GenerateMapChangeElementsTransition(masm, mode, &fail); |
723 } else if (IsFastDoubleElementsKind(from_)) { | 823 } else if (IsFastDoubleElementsKind(from_)) { |
724 ASSERT(!IsFastSmiElementsKind(to_)); | 824 ASSERT(!IsFastSmiElementsKind(to_)); |
725 ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, &fail); | 825 ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, &fail); |
726 } else { | 826 } else { |
(...skipping 23 matching lines...) Expand all Loading... |
750 | 850 |
751 | 851 |
752 void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) { | 852 void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) { |
753 StubFailureTrampolineStub stub1(NOT_JS_FUNCTION_STUB_MODE); | 853 StubFailureTrampolineStub stub1(NOT_JS_FUNCTION_STUB_MODE); |
754 StubFailureTrampolineStub stub2(JS_FUNCTION_STUB_MODE); | 854 StubFailureTrampolineStub stub2(JS_FUNCTION_STUB_MODE); |
755 stub1.GetCode(isolate)->set_is_pregenerated(true); | 855 stub1.GetCode(isolate)->set_is_pregenerated(true); |
756 stub2.GetCode(isolate)->set_is_pregenerated(true); | 856 stub2.GetCode(isolate)->set_is_pregenerated(true); |
757 } | 857 } |
758 | 858 |
759 | 859 |
760 FunctionEntryHook ProfileEntryHookStub::entry_hook_ = NULL; | |
761 | |
762 | |
763 void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function, | 860 void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function, |
764 intptr_t stack_pointer) { | 861 intptr_t stack_pointer) { |
765 if (entry_hook_ != NULL) | 862 FunctionEntryHook entry_hook = Isolate::Current()->function_entry_hook(); |
766 entry_hook_(function, stack_pointer); | 863 ASSERT(entry_hook != NULL); |
| 864 entry_hook(function, stack_pointer); |
767 } | 865 } |
768 | 866 |
769 | 867 |
770 bool ProfileEntryHookStub::SetFunctionEntryHook(FunctionEntryHook entry_hook) { | |
771 // We don't allow setting a new entry hook over one that's | |
772 // already active, as the hooks won't stack. | |
773 if (entry_hook != 0 && entry_hook_ != 0) | |
774 return false; | |
775 | |
776 entry_hook_ = entry_hook; | |
777 return true; | |
778 } | |
779 | |
780 | |
781 static void InstallDescriptor(Isolate* isolate, HydrogenCodeStub* stub) { | 868 static void InstallDescriptor(Isolate* isolate, HydrogenCodeStub* stub) { |
782 int major_key = stub->MajorKey(); | 869 int major_key = stub->MajorKey(); |
783 CodeStubInterfaceDescriptor* descriptor = | 870 CodeStubInterfaceDescriptor* descriptor = |
784 isolate->code_stub_interface_descriptor(major_key); | 871 isolate->code_stub_interface_descriptor(major_key); |
785 if (!descriptor->initialized()) { | 872 if (!descriptor->initialized()) { |
786 stub->InitializeInterfaceDescriptor(isolate, descriptor); | 873 stub->InitializeInterfaceDescriptor(isolate, descriptor); |
787 } | 874 } |
788 } | 875 } |
789 | 876 |
790 | 877 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 InstallDescriptor(isolate, &stub3); | 915 InstallDescriptor(isolate, &stub3); |
829 } | 916 } |
830 | 917 |
831 InternalArrayConstructorStub::InternalArrayConstructorStub( | 918 InternalArrayConstructorStub::InternalArrayConstructorStub( |
832 Isolate* isolate) { | 919 Isolate* isolate) { |
833 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 920 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
834 } | 921 } |
835 | 922 |
836 | 923 |
837 } } // namespace v8::internal | 924 } } // namespace v8::internal |
OLD | NEW |