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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 V(Instanceof) \ | 59 V(Instanceof) \ |
60 V(ConvertToDouble) \ | 60 V(ConvertToDouble) \ |
61 V(WriteInt32ToHeapNumber) \ | 61 V(WriteInt32ToHeapNumber) \ |
62 V(StackCheck) \ | 62 V(StackCheck) \ |
63 V(Interrupt) \ | 63 V(Interrupt) \ |
64 V(FastNewClosure) \ | 64 V(FastNewClosure) \ |
65 V(FastNewContext) \ | 65 V(FastNewContext) \ |
66 V(FastNewBlockContext) \ | 66 V(FastNewBlockContext) \ |
67 V(FastCloneShallowArray) \ | 67 V(FastCloneShallowArray) \ |
68 V(FastCloneShallowObject) \ | 68 V(FastCloneShallowObject) \ |
| 69 V(CreateAllocationSite) \ |
69 V(ToBoolean) \ | 70 V(ToBoolean) \ |
70 V(ToNumber) \ | 71 V(ToNumber) \ |
71 V(ArgumentsAccess) \ | 72 V(ArgumentsAccess) \ |
72 V(RegExpConstructResult) \ | 73 V(RegExpConstructResult) \ |
73 V(NumberToString) \ | 74 V(NumberToString) \ |
74 V(CEntry) \ | 75 V(CEntry) \ |
75 V(JSEntry) \ | 76 V(JSEntry) \ |
76 V(KeyedLoadElement) \ | 77 V(KeyedLoadElement) \ |
77 V(ArrayNoArgumentConstructor) \ | 78 V(ArrayNoArgumentConstructor) \ |
78 V(ArraySingleArgumentConstructor) \ | 79 V(ArraySingleArgumentConstructor) \ |
79 V(ArrayNArgumentsConstructor) \ | 80 V(ArrayNArgumentsConstructor) \ |
80 V(InternalArrayNoArgumentConstructor) \ | 81 V(InternalArrayNoArgumentConstructor) \ |
81 V(InternalArraySingleArgumentConstructor) \ | 82 V(InternalArraySingleArgumentConstructor) \ |
82 V(InternalArrayNArgumentsConstructor) \ | 83 V(InternalArrayNArgumentsConstructor) \ |
83 V(KeyedStoreElement) \ | 84 V(KeyedStoreElement) \ |
84 V(DebuggerStatement) \ | 85 V(DebuggerStatement) \ |
85 V(NameDictionaryLookup) \ | 86 V(NameDictionaryLookup) \ |
86 V(ElementsTransitionAndStore) \ | 87 V(ElementsTransitionAndStore) \ |
87 V(TransitionElementsKind) \ | 88 V(TransitionElementsKind) \ |
88 V(StoreArrayLiteralElement) \ | 89 V(StoreArrayLiteralElement) \ |
89 V(StubFailureTrampoline) \ | 90 V(StubFailureTrampoline) \ |
90 V(ArrayConstructor) \ | 91 V(ArrayConstructor) \ |
91 V(InternalArrayConstructor) \ | 92 V(InternalArrayConstructor) \ |
92 V(ProfileEntryHook) \ | 93 V(ProfileEntryHook) \ |
| 94 V(StoreGlobal) \ |
93 /* IC Handler stubs */ \ | 95 /* IC Handler stubs */ \ |
94 V(LoadField) \ | 96 V(LoadField) \ |
95 V(KeyedLoadField) | 97 V(KeyedLoadField) |
96 | 98 |
97 // List of code stubs only used on ARM platforms. | 99 // List of code stubs only used on ARM platforms. |
98 #if defined(V8_TARGET_ARCH_ARM) | 100 #if V8_TARGET_ARCH_ARM |
99 #define CODE_STUB_LIST_ARM(V) \ | 101 #define CODE_STUB_LIST_ARM(V) \ |
100 V(GetProperty) \ | 102 V(GetProperty) \ |
101 V(SetProperty) \ | 103 V(SetProperty) \ |
102 V(InvokeBuiltin) \ | 104 V(InvokeBuiltin) \ |
103 V(RegExpCEntry) \ | 105 V(RegExpCEntry) \ |
104 V(DirectCEntry) | 106 V(DirectCEntry) |
105 #elif defined(V8_TARGET_ARCH_A64) | 107 #elif V8_TARGET_ARCH_A64 |
106 #define CODE_STUB_LIST_ARM(V) \ | 108 #define CODE_STUB_LIST_ARM(V) \ |
107 V(GetProperty) \ | 109 V(GetProperty) \ |
108 V(SetProperty) \ | 110 V(SetProperty) \ |
109 V(InvokeBuiltin) \ | 111 V(InvokeBuiltin) \ |
110 V(DirectCEntry) | 112 V(DirectCEntry) |
111 #else | 113 #else |
112 #define CODE_STUB_LIST_ARM(V) | 114 #define CODE_STUB_LIST_ARM(V) |
113 #endif | 115 #endif |
114 | 116 |
115 // List of code stubs only used on MIPS platforms. | 117 // List of code stubs only used on MIPS platforms. |
116 #ifdef V8_TARGET_ARCH_MIPS | 118 #if V8_TARGET_ARCH_MIPS |
117 #define CODE_STUB_LIST_MIPS(V) \ | 119 #define CODE_STUB_LIST_MIPS(V) \ |
118 V(RegExpCEntry) \ | 120 V(RegExpCEntry) \ |
119 V(DirectCEntry) | 121 V(DirectCEntry) |
120 #else | 122 #else |
121 #define CODE_STUB_LIST_MIPS(V) | 123 #define CODE_STUB_LIST_MIPS(V) |
122 #endif | 124 #endif |
123 | 125 |
124 // Combined list of code stubs. | 126 // Combined list of code stubs. |
125 #define CODE_STUB_LIST(V) \ | 127 #define CODE_STUB_LIST(V) \ |
126 CODE_STUB_LIST_ALL_PLATFORMS(V) \ | 128 CODE_STUB_LIST_ALL_PLATFORMS(V) \ |
127 CODE_STUB_LIST_ARM(V) \ | 129 CODE_STUB_LIST_ARM(V) \ |
128 CODE_STUB_LIST_MIPS(V) | 130 CODE_STUB_LIST_MIPS(V) |
129 | 131 |
130 // Mode to overwrite BinaryExpression values. | 132 // Mode to overwrite BinaryExpression values. |
131 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; | 133 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; |
132 enum UnaryOverwriteMode { UNARY_OVERWRITE, UNARY_NO_OVERWRITE }; | |
133 | |
134 | 134 |
135 // Stub is base classes of all stubs. | 135 // Stub is base classes of all stubs. |
136 class CodeStub BASE_EMBEDDED { | 136 class CodeStub BASE_EMBEDDED { |
137 public: | 137 public: |
138 enum Major { | 138 enum Major { |
139 #define DEF_ENUM(name) name, | 139 #define DEF_ENUM(name) name, |
140 CODE_STUB_LIST(DEF_ENUM) | 140 CODE_STUB_LIST(DEF_ENUM) |
141 #undef DEF_ENUM | 141 #undef DEF_ENUM |
142 NoCache, // marker for stubs that do custom caching | 142 NoCache, // marker for stubs that do custom caching |
143 NUMBER_OF_IDS | 143 NUMBER_OF_IDS |
144 }; | 144 }; |
145 | 145 |
146 // Retrieve the code for the stub. Generate the code if needed. | 146 // Retrieve the code for the stub. Generate the code if needed. |
147 Handle<Code> GetCode(Isolate* isolate); | 147 Handle<Code> GetCode(Isolate* isolate); |
148 | 148 |
| 149 // Retrieve the code for the stub, make and return a copy of the code. |
| 150 Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate); |
149 static Major MajorKeyFromKey(uint32_t key) { | 151 static Major MajorKeyFromKey(uint32_t key) { |
150 return static_cast<Major>(MajorKeyBits::decode(key)); | 152 return static_cast<Major>(MajorKeyBits::decode(key)); |
151 } | 153 } |
152 static int MinorKeyFromKey(uint32_t key) { | 154 static int MinorKeyFromKey(uint32_t key) { |
153 return MinorKeyBits::decode(key); | 155 return MinorKeyBits::decode(key); |
154 } | 156 } |
155 | 157 |
156 // Gets the major key from a code object that is a code stub or binary op IC. | 158 // Gets the major key from a code object that is a code stub or binary op IC. |
157 static Major GetMajorKey(Code* code_stub) { | 159 static Major GetMajorKey(Code* code_stub) { |
158 return static_cast<Major>(code_stub->major_key()); | 160 return static_cast<Major>(code_stub->major_key()); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 virtual Code::ExtraICState GetExtraICState() { | 198 virtual Code::ExtraICState GetExtraICState() { |
197 return Code::kNoExtraICState; | 199 return Code::kNoExtraICState; |
198 } | 200 } |
199 virtual Code::StubType GetStubType() { | 201 virtual Code::StubType GetStubType() { |
200 return Code::NORMAL; | 202 return Code::NORMAL; |
201 } | 203 } |
202 virtual int GetStubFlags() { | 204 virtual int GetStubFlags() { |
203 return -1; | 205 return -1; |
204 } | 206 } |
205 | 207 |
| 208 virtual void PrintName(StringStream* stream); |
| 209 |
206 protected: | 210 protected: |
207 static bool CanUseFPRegisters(); | 211 static bool CanUseFPRegisters(); |
208 | 212 |
209 // Generates the assembler code for the stub. | 213 // Generates the assembler code for the stub. |
210 virtual Handle<Code> GenerateCode() = 0; | 214 virtual Handle<Code> GenerateCode() = 0; |
211 | 215 |
212 | 216 |
213 // Returns whether the code generated for this stub needs to be allocated as | 217 // Returns whether the code generated for this stub needs to be allocated as |
214 // a fixed (non-moveable) code object. | 218 // a fixed (non-moveable) code object. |
215 virtual bool NeedsImmovableCode() { return false; } | 219 virtual bool NeedsImmovableCode() { return false; } |
216 | 220 |
| 221 // Returns a name for logging/debugging purposes. |
| 222 SmartArrayPointer<const char> GetName(); |
| 223 virtual void PrintBaseName(StringStream* stream); |
| 224 virtual void PrintState(StringStream* stream) { } |
| 225 |
217 private: | 226 private: |
218 // Perform bookkeeping required after code generation when stub code is | 227 // Perform bookkeeping required after code generation when stub code is |
219 // initially generated. | 228 // initially generated. |
220 void RecordCodeGeneration(Code* code, Isolate* isolate); | 229 void RecordCodeGeneration(Code* code, Isolate* isolate); |
221 | 230 |
222 // Finish the code object after it has been generated. | 231 // Finish the code object after it has been generated. |
223 virtual void FinishCode(Handle<Code> code) { } | 232 virtual void FinishCode(Handle<Code> code) { } |
224 | 233 |
225 // Activate newly generated stub. Is called after | 234 // Activate newly generated stub. Is called after |
226 // registering stub in the stub cache. | 235 // registering stub in the stub cache. |
227 virtual void Activate(Code* code) { } | 236 virtual void Activate(Code* code) { } |
228 | 237 |
229 // BinaryOpStub needs to override this. | 238 // BinaryOpStub needs to override this. |
230 virtual Code::Kind GetCodeKind() const; | 239 virtual Code::Kind GetCodeKind() const; |
231 | 240 |
232 // Add the code to a specialized cache, specific to an individual | 241 // Add the code to a specialized cache, specific to an individual |
233 // stub type. Please note, this method must add the code object to a | 242 // stub type. Please note, this method must add the code object to a |
234 // roots object, otherwise we will remove the code during GC. | 243 // roots object, otherwise we will remove the code during GC. |
235 virtual void AddToSpecialCache(Handle<Code> new_object) { } | 244 virtual void AddToSpecialCache(Handle<Code> new_object) { } |
236 | 245 |
237 // Find code in a specialized cache, work is delegated to the specific stub. | 246 // Find code in a specialized cache, work is delegated to the specific stub. |
238 virtual bool FindCodeInSpecialCache(Code** code_out, Isolate* isolate) { | 247 virtual bool FindCodeInSpecialCache(Code** code_out, Isolate* isolate) { |
239 return false; | 248 return false; |
240 } | 249 } |
241 | 250 |
242 // If a stub uses a special cache override this. | 251 // If a stub uses a special cache override this. |
243 virtual bool UseSpecialCache() { return false; } | 252 virtual bool UseSpecialCache() { return false; } |
244 | 253 |
245 // Returns a name for logging/debugging purposes. | |
246 SmartArrayPointer<const char> GetName(); | |
247 virtual void PrintName(StringStream* stream); | |
248 | |
249 // Computes the key based on major and minor. | 254 // Computes the key based on major and minor. |
250 uint32_t GetKey() { | 255 uint32_t GetKey() { |
251 ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS); | 256 ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS); |
252 return MinorKeyBits::encode(MinorKey()) | | 257 return MinorKeyBits::encode(MinorKey()) | |
253 MajorKeyBits::encode(MajorKey()); | 258 MajorKeyBits::encode(MajorKey()); |
254 } | 259 } |
255 | 260 |
256 class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {}; | 261 class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {}; |
257 class MinorKeyBits: public BitField<uint32_t, | 262 class MinorKeyBits: public BitField<uint32_t, |
258 kStubMajorKeyBits, kStubMinorKeyBits> {}; // NOLINT | 263 kStubMajorKeyBits, kStubMinorKeyBits> {}; // NOLINT |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 Isolate* isolate, | 358 Isolate* isolate, |
354 CodeStubInterfaceDescriptor* descriptor) = 0; | 359 CodeStubInterfaceDescriptor* descriptor) = 0; |
355 | 360 |
356 // Retrieve the code for the stub. Generate the code if needed. | 361 // Retrieve the code for the stub. Generate the code if needed. |
357 virtual Handle<Code> GenerateCode() = 0; | 362 virtual Handle<Code> GenerateCode() = 0; |
358 | 363 |
359 virtual int NotMissMinorKey() = 0; | 364 virtual int NotMissMinorKey() = 0; |
360 | 365 |
361 Handle<Code> GenerateLightweightMissCode(Isolate* isolate); | 366 Handle<Code> GenerateLightweightMissCode(Isolate* isolate); |
362 | 367 |
| 368 template<class StateType> |
| 369 void TraceTransition(StateType from, StateType to); |
| 370 |
363 private: | 371 private: |
364 class MinorKeyBits: public BitField<int, 0, kStubMinorKeyBits - 1> {}; | 372 class MinorKeyBits: public BitField<int, 0, kStubMinorKeyBits - 1> {}; |
365 class IsMissBits: public BitField<bool, kStubMinorKeyBits - 1, 1> {}; | 373 class IsMissBits: public BitField<bool, kStubMinorKeyBits - 1, 1> {}; |
366 | 374 |
367 void GenerateLightweightMiss(MacroAssembler* masm); | 375 void GenerateLightweightMiss(MacroAssembler* masm); |
368 virtual int MinorKey() { | 376 virtual int MinorKey() { |
369 return IsMissBits::encode(is_uninitialized_) | | 377 return IsMissBits::encode(is_uninitialized_) | |
370 MinorKeyBits::encode(NotMissMinorKey()); | 378 MinorKeyBits::encode(NotMissMinorKey()); |
371 } | 379 } |
372 | 380 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 | 528 |
521 void Generate(MacroAssembler* masm); | 529 void Generate(MacroAssembler* masm); |
522 | 530 |
523 private: | 531 private: |
524 int slots_; | 532 int slots_; |
525 | 533 |
526 Major MajorKey() { return FastNewBlockContext; } | 534 Major MajorKey() { return FastNewBlockContext; } |
527 int MinorKey() { return slots_; } | 535 int MinorKey() { return slots_; } |
528 }; | 536 }; |
529 | 537 |
| 538 class StoreGlobalStub : public HydrogenCodeStub { |
| 539 public: |
| 540 StoreGlobalStub(StrictModeFlag strict_mode, bool is_constant) { |
| 541 bit_field_ = StrictModeBits::encode(strict_mode) | |
| 542 IsConstantBits::encode(is_constant); |
| 543 } |
| 544 |
| 545 virtual Handle<Code> GenerateCode(); |
| 546 |
| 547 virtual void InitializeInterfaceDescriptor( |
| 548 Isolate* isolate, |
| 549 CodeStubInterfaceDescriptor* descriptor); |
| 550 |
| 551 virtual Code::Kind GetCodeKind() const { return Code::STORE_IC; } |
| 552 virtual InlineCacheState GetICState() { return MONOMORPHIC; } |
| 553 virtual Code::ExtraICState GetExtraICState() { return bit_field_; } |
| 554 |
| 555 bool is_constant() { |
| 556 return IsConstantBits::decode(bit_field_); |
| 557 } |
| 558 void set_is_constant(bool value) { |
| 559 bit_field_ = IsConstantBits::update(bit_field_, value); |
| 560 } |
| 561 |
| 562 Representation representation() { |
| 563 return Representation::FromKind(RepresentationBits::decode(bit_field_)); |
| 564 } |
| 565 void set_representation(Representation r) { |
| 566 bit_field_ = RepresentationBits::update(bit_field_, r.kind()); |
| 567 } |
| 568 |
| 569 private: |
| 570 virtual int NotMissMinorKey() { return GetExtraICState(); } |
| 571 Major MajorKey() { return StoreGlobal; } |
| 572 |
| 573 class StrictModeBits: public BitField<StrictModeFlag, 0, 1> {}; |
| 574 class IsConstantBits: public BitField<bool, 1, 1> {}; |
| 575 class RepresentationBits: public BitField<Representation::Kind, 2, 8> {}; |
| 576 |
| 577 int bit_field_; |
| 578 |
| 579 DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub); |
| 580 }; |
| 581 |
| 582 |
| 583 class UnaryOpStub : public HydrogenCodeStub { |
| 584 public: |
| 585 // Stub without type info available -> construct uninitialized |
| 586 explicit UnaryOpStub(Token::Value operation) |
| 587 : HydrogenCodeStub(UNINITIALIZED), operation_(operation) { } |
| 588 explicit UnaryOpStub(Code::ExtraICState ic_state) : |
| 589 state_(StateBits::decode(ic_state)), |
| 590 operation_(OperatorBits::decode(ic_state)) { } |
| 591 |
| 592 virtual void InitializeInterfaceDescriptor( |
| 593 Isolate* isolate, |
| 594 CodeStubInterfaceDescriptor* descriptor); |
| 595 |
| 596 virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; } |
| 597 virtual InlineCacheState GetICState() { |
| 598 if (state_.Contains(GENERIC)) { |
| 599 return MEGAMORPHIC; |
| 600 } else if (state_.IsEmpty()) { |
| 601 return PREMONOMORPHIC; |
| 602 } else { |
| 603 return MONOMORPHIC; |
| 604 } |
| 605 } |
| 606 virtual Code::ExtraICState GetExtraICState() { |
| 607 return OperatorBits::encode(operation_) | |
| 608 StateBits::encode(state_.ToIntegral()); |
| 609 } |
| 610 |
| 611 Token::Value operation() { return operation_; } |
| 612 Handle<JSFunction> ToJSFunction(Isolate* isolate); |
| 613 Builtins::JavaScript ToJSBuiltin(); |
| 614 |
| 615 void UpdateStatus(Handle<Object> object); |
| 616 MaybeObject* Result(Handle<Object> object, Isolate* isolate); |
| 617 Handle<Code> GenerateCode(); |
| 618 Handle<Type> GetType(Isolate* isolate); |
| 619 |
| 620 protected: |
| 621 void PrintState(StringStream* stream); |
| 622 void PrintBaseName(StringStream* stream); |
| 623 |
| 624 private: |
| 625 enum UnaryOpType { |
| 626 SMI, |
| 627 HEAP_NUMBER, |
| 628 GENERIC, |
| 629 NUMBER_OF_TYPES |
| 630 }; |
| 631 |
| 632 class State : public EnumSet<UnaryOpType, byte> { |
| 633 public: |
| 634 State() : EnumSet<UnaryOpType, byte>() { } |
| 635 explicit State(byte bits) : EnumSet<UnaryOpType, byte>(bits) { } |
| 636 void Print(StringStream* stream) const; |
| 637 }; |
| 638 |
| 639 class StateBits : public BitField<int, 0, NUMBER_OF_TYPES> { }; |
| 640 class OperatorBits : public BitField<Token::Value, NUMBER_OF_TYPES, 8> { }; |
| 641 |
| 642 State state_; |
| 643 Token::Value operation_; |
| 644 |
| 645 virtual CodeStub::Major MajorKey() { return UnaryOp; } |
| 646 virtual int NotMissMinorKey() { return GetExtraICState(); } |
| 647 }; |
| 648 |
530 | 649 |
531 class FastCloneShallowArrayStub : public HydrogenCodeStub { | 650 class FastCloneShallowArrayStub : public HydrogenCodeStub { |
532 public: | 651 public: |
533 // Maximum length of copied elements array. | 652 // Maximum length of copied elements array. |
534 static const int kMaximumClonedLength = 8; | 653 static const int kMaximumClonedLength = 8; |
535 enum Mode { | 654 enum Mode { |
536 CLONE_ELEMENTS, | 655 CLONE_ELEMENTS, |
537 CLONE_DOUBLE_ELEMENTS, | 656 CLONE_DOUBLE_ELEMENTS, |
538 COPY_ON_WRITE_ELEMENTS, | 657 COPY_ON_WRITE_ELEMENTS, |
539 CLONE_ANY_ELEMENTS, | 658 CLONE_ANY_ELEMENTS, |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 private: | 740 private: |
622 int length_; | 741 int length_; |
623 | 742 |
624 Major MajorKey() { return FastCloneShallowObject; } | 743 Major MajorKey() { return FastCloneShallowObject; } |
625 int NotMissMinorKey() { return length_; } | 744 int NotMissMinorKey() { return length_; } |
626 | 745 |
627 DISALLOW_COPY_AND_ASSIGN(FastCloneShallowObjectStub); | 746 DISALLOW_COPY_AND_ASSIGN(FastCloneShallowObjectStub); |
628 }; | 747 }; |
629 | 748 |
630 | 749 |
| 750 class CreateAllocationSiteStub : public HydrogenCodeStub { |
| 751 public: |
| 752 explicit CreateAllocationSiteStub() { } |
| 753 |
| 754 virtual Handle<Code> GenerateCode(); |
| 755 |
| 756 virtual bool IsPregenerated() { return true; } |
| 757 |
| 758 static void GenerateAheadOfTime(Isolate* isolate); |
| 759 |
| 760 virtual void InitializeInterfaceDescriptor( |
| 761 Isolate* isolate, |
| 762 CodeStubInterfaceDescriptor* descriptor); |
| 763 |
| 764 private: |
| 765 Major MajorKey() { return CreateAllocationSite; } |
| 766 int NotMissMinorKey() { return 0; } |
| 767 |
| 768 DISALLOW_COPY_AND_ASSIGN(CreateAllocationSiteStub); |
| 769 }; |
| 770 |
| 771 |
631 class InstanceofStub: public PlatformCodeStub { | 772 class InstanceofStub: public PlatformCodeStub { |
632 public: | 773 public: |
633 enum Flags { | 774 enum Flags { |
634 kNoFlags = 0, | 775 kNoFlags = 0, |
635 kArgsInRegisters = 1 << 0, | 776 kArgsInRegisters = 1 << 0, |
636 kCallSiteInlineCheck = 1 << 1, | 777 kCallSiteInlineCheck = 1 << 1, |
637 kReturnTrueFalseObject = 1 << 2 | 778 kReturnTrueFalseObject = 1 << 2 |
638 }; | 779 }; |
639 | 780 |
640 explicit InstanceofStub(Flags flags) : flags_(flags) { } | 781 explicit InstanceofStub(Flags flags) : flags_(flags) { } |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 static State Generic() { | 1285 static State Generic() { |
1145 State set; | 1286 State set; |
1146 set.Add(UNDEFINED); | 1287 set.Add(UNDEFINED); |
1147 set.Add(NULL_TYPE); | 1288 set.Add(NULL_TYPE); |
1148 set.Add(UNDETECTABLE); | 1289 set.Add(UNDETECTABLE); |
1149 set.Add(GENERIC); | 1290 set.Add(GENERIC); |
1150 return set; | 1291 return set; |
1151 } | 1292 } |
1152 | 1293 |
1153 void Print(StringStream* stream) const; | 1294 void Print(StringStream* stream) const; |
1154 void TraceTransition(State to) const; | |
1155 }; | 1295 }; |
1156 | 1296 |
1157 static Handle<Type> StateToType( | 1297 static Handle<Type> StateToType( |
1158 Isolate* isolate, State state, Handle<Map> map = Handle<Map>()); | 1298 Isolate* isolate, State state, Handle<Map> map = Handle<Map>()); |
1159 | 1299 |
1160 // At most 6 different types can be distinguished, because the Code object | 1300 // At most 6 different types can be distinguished, because the Code object |
1161 // only has room for a single byte to hold a set and there are two more | 1301 // only has room for a single byte to hold a set and there are two more |
1162 // boolean flags we need to store. :-P | 1302 // boolean flags we need to store. :-P |
1163 STATIC_ASSERT(NUMBER_OF_TYPES <= 6); | 1303 STATIC_ASSERT(NUMBER_OF_TYPES <= 6); |
1164 | 1304 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 virtual Code::ExtraICState GetExtraICState() { | 1347 virtual Code::ExtraICState GetExtraICState() { |
1208 return NilValueField::encode(nil_value_) | state_.ToIntegral(); | 1348 return NilValueField::encode(nil_value_) | state_.ToIntegral(); |
1209 } | 1349 } |
1210 static byte ExtractTypesFromExtraICState(Code::ExtraICState state) { | 1350 static byte ExtractTypesFromExtraICState(Code::ExtraICState state) { |
1211 return state & ((1 << NUMBER_OF_TYPES) - 1); | 1351 return state & ((1 << NUMBER_OF_TYPES) - 1); |
1212 } | 1352 } |
1213 static NilValue ExtractNilValueFromExtraICState(Code::ExtraICState state) { | 1353 static NilValue ExtractNilValueFromExtraICState(Code::ExtraICState state) { |
1214 return NilValueField::decode(state); | 1354 return NilValueField::decode(state); |
1215 } | 1355 } |
1216 | 1356 |
1217 void Record(Handle<Object> object); | 1357 void UpdateStatus(Handle<Object> object); |
1218 | 1358 |
1219 bool IsMonomorphic() const { return state_.Contains(MONOMORPHIC_MAP); } | 1359 bool IsMonomorphic() const { return state_.Contains(MONOMORPHIC_MAP); } |
1220 NilValue GetNilValue() const { return nil_value_; } | 1360 NilValue GetNilValue() const { return nil_value_; } |
1221 State GetState() const { return state_; } | 1361 State GetState() const { return state_; } |
1222 void ClearState() { state_.RemoveAll(); } | 1362 void ClearState() { state_.RemoveAll(); } |
1223 | 1363 |
1224 virtual void PrintName(StringStream* stream); | 1364 virtual void PrintState(StringStream* stream); |
| 1365 virtual void PrintBaseName(StringStream* stream); |
1225 | 1366 |
1226 private: | 1367 private: |
1227 friend class CompareNilIC; | 1368 friend class CompareNilIC; |
1228 | 1369 |
1229 CompareNilICStub(NilValue nil, InitializationState init_state) | 1370 CompareNilICStub(NilValue nil, InitializationState init_state) |
1230 : HydrogenCodeStub(init_state) { | 1371 : HydrogenCodeStub(init_state) { |
1231 nil_value_ = nil; | 1372 nil_value_ = nil; |
1232 } | 1373 } |
1233 | 1374 |
1234 class NilValueField : public BitField<NilValue, NUMBER_OF_TYPES, 1> {}; | 1375 class NilValueField : public BitField<NilValue, NUMBER_OF_TYPES, 1> {}; |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1734 class ToKindBits: public BitField<ElementsKind, 0, 8> {}; | 1875 class ToKindBits: public BitField<ElementsKind, 0, 8> {}; |
1735 uint32_t bit_field_; | 1876 uint32_t bit_field_; |
1736 | 1877 |
1737 Major MajorKey() { return TransitionElementsKind; } | 1878 Major MajorKey() { return TransitionElementsKind; } |
1738 int NotMissMinorKey() { return bit_field_; } | 1879 int NotMissMinorKey() { return bit_field_; } |
1739 | 1880 |
1740 DISALLOW_COPY_AND_ASSIGN(TransitionElementsKindStub); | 1881 DISALLOW_COPY_AND_ASSIGN(TransitionElementsKindStub); |
1741 }; | 1882 }; |
1742 | 1883 |
1743 | 1884 |
| 1885 enum ContextCheckMode { |
| 1886 CONTEXT_CHECK_REQUIRED, |
| 1887 CONTEXT_CHECK_NOT_REQUIRED, |
| 1888 LAST_CONTEXT_CHECK_MODE = CONTEXT_CHECK_NOT_REQUIRED |
| 1889 }; |
| 1890 |
| 1891 |
| 1892 enum AllocationSiteOverrideMode { |
| 1893 DONT_OVERRIDE, |
| 1894 DISABLE_ALLOCATION_SITES, |
| 1895 LAST_ALLOCATION_SITE_OVERRIDE_MODE = DISABLE_ALLOCATION_SITES |
| 1896 }; |
| 1897 |
| 1898 |
1744 class ArrayConstructorStubBase : public HydrogenCodeStub { | 1899 class ArrayConstructorStubBase : public HydrogenCodeStub { |
1745 public: | 1900 public: |
1746 ArrayConstructorStubBase(ElementsKind kind, bool disable_allocation_sites) { | 1901 ArrayConstructorStubBase(ElementsKind kind, ContextCheckMode context_mode, |
| 1902 AllocationSiteOverrideMode override_mode) { |
1747 // It only makes sense to override local allocation site behavior | 1903 // It only makes sense to override local allocation site behavior |
1748 // if there is a difference between the global allocation site policy | 1904 // if there is a difference between the global allocation site policy |
1749 // for an ElementsKind and the desired usage of the stub. | 1905 // for an ElementsKind and the desired usage of the stub. |
1750 ASSERT(!disable_allocation_sites || | 1906 ASSERT(override_mode != DISABLE_ALLOCATION_SITES || |
1751 AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE); | 1907 AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE); |
1752 bit_field_ = ElementsKindBits::encode(kind) | | 1908 bit_field_ = ElementsKindBits::encode(kind) | |
1753 DisableAllocationSitesBits::encode(disable_allocation_sites); | 1909 AllocationSiteOverrideModeBits::encode(override_mode) | |
| 1910 ContextCheckModeBits::encode(context_mode); |
1754 } | 1911 } |
1755 | 1912 |
1756 ElementsKind elements_kind() const { | 1913 ElementsKind elements_kind() const { |
1757 return ElementsKindBits::decode(bit_field_); | 1914 return ElementsKindBits::decode(bit_field_); |
1758 } | 1915 } |
1759 | 1916 |
1760 bool disable_allocation_sites() const { | 1917 AllocationSiteOverrideMode override_mode() const { |
1761 return DisableAllocationSitesBits::decode(bit_field_); | 1918 return AllocationSiteOverrideModeBits::decode(bit_field_); |
1762 } | 1919 } |
1763 | 1920 |
1764 virtual bool IsPregenerated() { return true; } | 1921 ContextCheckMode context_mode() const { |
| 1922 return ContextCheckModeBits::decode(bit_field_); |
| 1923 } |
| 1924 |
| 1925 virtual bool IsPregenerated() { |
| 1926 // We only pre-generate stubs that verify correct context |
| 1927 return context_mode() == CONTEXT_CHECK_REQUIRED; |
| 1928 } |
| 1929 |
1765 static void GenerateStubsAheadOfTime(Isolate* isolate); | 1930 static void GenerateStubsAheadOfTime(Isolate* isolate); |
1766 static void InstallDescriptors(Isolate* isolate); | 1931 static void InstallDescriptors(Isolate* isolate); |
1767 | 1932 |
1768 // Parameters accessed via CodeStubGraphBuilder::GetParameter() | 1933 // Parameters accessed via CodeStubGraphBuilder::GetParameter() |
1769 static const int kConstructor = 0; | 1934 static const int kConstructor = 0; |
1770 static const int kPropertyCell = 1; | 1935 static const int kPropertyCell = 1; |
1771 | 1936 |
1772 private: | 1937 private: |
1773 int NotMissMinorKey() { return bit_field_; } | 1938 int NotMissMinorKey() { return bit_field_; } |
1774 | 1939 |
| 1940 // Ensure data fits within available bits. |
| 1941 STATIC_ASSERT(LAST_ALLOCATION_SITE_OVERRIDE_MODE == 1); |
| 1942 STATIC_ASSERT(LAST_CONTEXT_CHECK_MODE == 1); |
| 1943 |
1775 class ElementsKindBits: public BitField<ElementsKind, 0, 8> {}; | 1944 class ElementsKindBits: public BitField<ElementsKind, 0, 8> {}; |
1776 class DisableAllocationSitesBits: public BitField<bool, 8, 1> {}; | 1945 class AllocationSiteOverrideModeBits: public |
| 1946 BitField<AllocationSiteOverrideMode, 8, 1> {}; // NOLINT |
| 1947 class ContextCheckModeBits: public BitField<ContextCheckMode, 9, 1> {}; |
1777 uint32_t bit_field_; | 1948 uint32_t bit_field_; |
1778 | 1949 |
1779 DISALLOW_COPY_AND_ASSIGN(ArrayConstructorStubBase); | 1950 DISALLOW_COPY_AND_ASSIGN(ArrayConstructorStubBase); |
1780 }; | 1951 }; |
1781 | 1952 |
1782 | 1953 |
1783 class ArrayNoArgumentConstructorStub : public ArrayConstructorStubBase { | 1954 class ArrayNoArgumentConstructorStub : public ArrayConstructorStubBase { |
1784 public: | 1955 public: |
1785 ArrayNoArgumentConstructorStub( | 1956 ArrayNoArgumentConstructorStub( |
1786 ElementsKind kind, | 1957 ElementsKind kind, |
1787 bool disable_allocation_sites = false) | 1958 ContextCheckMode context_mode = CONTEXT_CHECK_REQUIRED, |
1788 : ArrayConstructorStubBase(kind, disable_allocation_sites) { | 1959 AllocationSiteOverrideMode override_mode = DONT_OVERRIDE) |
| 1960 : ArrayConstructorStubBase(kind, context_mode, override_mode) { |
1789 } | 1961 } |
1790 | 1962 |
1791 virtual Handle<Code> GenerateCode(); | 1963 virtual Handle<Code> GenerateCode(); |
1792 | 1964 |
1793 virtual void InitializeInterfaceDescriptor( | 1965 virtual void InitializeInterfaceDescriptor( |
1794 Isolate* isolate, | 1966 Isolate* isolate, |
1795 CodeStubInterfaceDescriptor* descriptor); | 1967 CodeStubInterfaceDescriptor* descriptor); |
1796 | 1968 |
1797 private: | 1969 private: |
1798 Major MajorKey() { return ArrayNoArgumentConstructor; } | 1970 Major MajorKey() { return ArrayNoArgumentConstructor; } |
1799 | 1971 |
1800 DISALLOW_COPY_AND_ASSIGN(ArrayNoArgumentConstructorStub); | 1972 DISALLOW_COPY_AND_ASSIGN(ArrayNoArgumentConstructorStub); |
1801 }; | 1973 }; |
1802 | 1974 |
1803 | 1975 |
1804 class ArraySingleArgumentConstructorStub : public ArrayConstructorStubBase { | 1976 class ArraySingleArgumentConstructorStub : public ArrayConstructorStubBase { |
1805 public: | 1977 public: |
1806 ArraySingleArgumentConstructorStub( | 1978 ArraySingleArgumentConstructorStub( |
1807 ElementsKind kind, | 1979 ElementsKind kind, |
1808 bool disable_allocation_sites = false) | 1980 ContextCheckMode context_mode = CONTEXT_CHECK_REQUIRED, |
1809 : ArrayConstructorStubBase(kind, disable_allocation_sites) { | 1981 AllocationSiteOverrideMode override_mode = DONT_OVERRIDE) |
| 1982 : ArrayConstructorStubBase(kind, context_mode, override_mode) { |
1810 } | 1983 } |
1811 | 1984 |
1812 virtual Handle<Code> GenerateCode(); | 1985 virtual Handle<Code> GenerateCode(); |
1813 | 1986 |
1814 virtual void InitializeInterfaceDescriptor( | 1987 virtual void InitializeInterfaceDescriptor( |
1815 Isolate* isolate, | 1988 Isolate* isolate, |
1816 CodeStubInterfaceDescriptor* descriptor); | 1989 CodeStubInterfaceDescriptor* descriptor); |
1817 | 1990 |
1818 private: | 1991 private: |
1819 Major MajorKey() { return ArraySingleArgumentConstructor; } | 1992 Major MajorKey() { return ArraySingleArgumentConstructor; } |
1820 | 1993 |
1821 DISALLOW_COPY_AND_ASSIGN(ArraySingleArgumentConstructorStub); | 1994 DISALLOW_COPY_AND_ASSIGN(ArraySingleArgumentConstructorStub); |
1822 }; | 1995 }; |
1823 | 1996 |
1824 | 1997 |
1825 class ArrayNArgumentsConstructorStub : public ArrayConstructorStubBase { | 1998 class ArrayNArgumentsConstructorStub : public ArrayConstructorStubBase { |
1826 public: | 1999 public: |
1827 ArrayNArgumentsConstructorStub( | 2000 ArrayNArgumentsConstructorStub( |
1828 ElementsKind kind, | 2001 ElementsKind kind, |
1829 bool disable_allocation_sites = false) | 2002 ContextCheckMode context_mode = CONTEXT_CHECK_REQUIRED, |
1830 : ArrayConstructorStubBase(kind, disable_allocation_sites) { | 2003 AllocationSiteOverrideMode override_mode = DONT_OVERRIDE) |
| 2004 : ArrayConstructorStubBase(kind, context_mode, override_mode) { |
1831 } | 2005 } |
1832 | 2006 |
1833 virtual Handle<Code> GenerateCode(); | 2007 virtual Handle<Code> GenerateCode(); |
1834 | 2008 |
1835 virtual void InitializeInterfaceDescriptor( | 2009 virtual void InitializeInterfaceDescriptor( |
1836 Isolate* isolate, | 2010 Isolate* isolate, |
1837 CodeStubInterfaceDescriptor* descriptor); | 2011 CodeStubInterfaceDescriptor* descriptor); |
1838 | 2012 |
1839 private: | 2013 private: |
1840 Major MajorKey() { return ArrayNArgumentsConstructor; } | 2014 Major MajorKey() { return ArrayNArgumentsConstructor; } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1977 // only has room for a single byte to hold a set of these types. :-P | 2151 // only has room for a single byte to hold a set of these types. :-P |
1978 STATIC_ASSERT(NUMBER_OF_TYPES <= 8); | 2152 STATIC_ASSERT(NUMBER_OF_TYPES <= 8); |
1979 | 2153 |
1980 class Types : public EnumSet<Type, byte> { | 2154 class Types : public EnumSet<Type, byte> { |
1981 public: | 2155 public: |
1982 Types() : EnumSet<Type, byte>(0) {} | 2156 Types() : EnumSet<Type, byte>(0) {} |
1983 explicit Types(byte bits) : EnumSet<Type, byte>(bits) {} | 2157 explicit Types(byte bits) : EnumSet<Type, byte>(bits) {} |
1984 | 2158 |
1985 byte ToByte() const { return ToIntegral(); } | 2159 byte ToByte() const { return ToIntegral(); } |
1986 void Print(StringStream* stream) const; | 2160 void Print(StringStream* stream) const; |
1987 void TraceTransition(Types to) const; | 2161 bool UpdateStatus(Handle<Object> object); |
1988 bool Record(Handle<Object> object); | |
1989 bool NeedsMap() const; | 2162 bool NeedsMap() const; |
1990 bool CanBeUndetectable() const; | 2163 bool CanBeUndetectable() const; |
1991 bool IsGeneric() const { return ToIntegral() == Generic().ToIntegral(); } | 2164 bool IsGeneric() const { return ToIntegral() == Generic().ToIntegral(); } |
1992 | 2165 |
1993 static Types Generic() { return Types((1 << NUMBER_OF_TYPES) - 1); } | 2166 static Types Generic() { return Types((1 << NUMBER_OF_TYPES) - 1); } |
1994 }; | 2167 }; |
1995 | 2168 |
1996 explicit ToBooleanStub(Types types = Types()) | 2169 explicit ToBooleanStub(Types types = Types()) |
1997 : types_(types) { } | 2170 : types_(types) { } |
1998 explicit ToBooleanStub(Code::ExtraICState state) | 2171 explicit ToBooleanStub(Code::ExtraICState state) |
1999 : types_(static_cast<byte>(state)) { } | 2172 : types_(static_cast<byte>(state)) { } |
2000 | 2173 |
2001 bool Record(Handle<Object> object); | 2174 bool UpdateStatus(Handle<Object> object); |
2002 Types GetTypes() { return types_; } | 2175 Types GetTypes() { return types_; } |
2003 | 2176 |
2004 virtual Handle<Code> GenerateCode(); | 2177 virtual Handle<Code> GenerateCode(); |
2005 virtual void InitializeInterfaceDescriptor( | 2178 virtual void InitializeInterfaceDescriptor( |
2006 Isolate* isolate, | 2179 Isolate* isolate, |
2007 CodeStubInterfaceDescriptor* descriptor); | 2180 CodeStubInterfaceDescriptor* descriptor); |
2008 | 2181 |
2009 virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; } | 2182 virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; } |
2010 virtual void PrintName(StringStream* stream); | 2183 virtual void PrintState(StringStream* stream); |
2011 | 2184 |
2012 virtual bool SometimesSetsUpAFrame() { return false; } | 2185 virtual bool SometimesSetsUpAFrame() { return false; } |
2013 | 2186 |
2014 static void InitializeForIsolate(Isolate* isolate) { | 2187 static void InitializeForIsolate(Isolate* isolate) { |
2015 ToBooleanStub stub; | 2188 ToBooleanStub stub; |
2016 stub.InitializeInterfaceDescriptor( | 2189 stub.InitializeInterfaceDescriptor( |
2017 isolate, | 2190 isolate, |
2018 isolate->code_stub_interface_descriptor(CodeStub::ToBoolean)); | 2191 isolate->code_stub_interface_descriptor(CodeStub::ToBoolean)); |
2019 } | 2192 } |
2020 | 2193 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2136 class ProfileEntryHookStub : public PlatformCodeStub { | 2309 class ProfileEntryHookStub : public PlatformCodeStub { |
2137 public: | 2310 public: |
2138 explicit ProfileEntryHookStub() {} | 2311 explicit ProfileEntryHookStub() {} |
2139 | 2312 |
2140 // The profile entry hook function is not allowed to cause a GC. | 2313 // The profile entry hook function is not allowed to cause a GC. |
2141 virtual bool SometimesSetsUpAFrame() { return false; } | 2314 virtual bool SometimesSetsUpAFrame() { return false; } |
2142 | 2315 |
2143 // Generates a call to the entry hook if it's enabled. | 2316 // Generates a call to the entry hook if it's enabled. |
2144 static void MaybeCallEntryHook(MacroAssembler* masm); | 2317 static void MaybeCallEntryHook(MacroAssembler* masm); |
2145 | 2318 |
2146 // Sets or unsets the entry hook function. Returns true on success, | |
2147 // false on an attempt to replace a non-NULL entry hook with another | |
2148 // non-NULL hook. | |
2149 static bool SetFunctionEntryHook(FunctionEntryHook entry_hook); | |
2150 | |
2151 static bool HasEntryHook() { return entry_hook_ != NULL; } | |
2152 | |
2153 private: | 2319 private: |
2154 static void EntryHookTrampoline(intptr_t function, | 2320 static void EntryHookTrampoline(intptr_t function, |
2155 intptr_t stack_pointer); | 2321 intptr_t stack_pointer); |
2156 | 2322 |
2157 Major MajorKey() { return ProfileEntryHook; } | 2323 Major MajorKey() { return ProfileEntryHook; } |
2158 int MinorKey() { return 0; } | 2324 int MinorKey() { return 0; } |
2159 | 2325 |
2160 void Generate(MacroAssembler* masm); | 2326 void Generate(MacroAssembler* masm); |
2161 | 2327 |
2162 // The current function entry hook. | |
2163 static FunctionEntryHook entry_hook_; | |
2164 | |
2165 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); | 2328 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); |
2166 }; | 2329 }; |
2167 | 2330 |
2168 } } // namespace v8::internal | 2331 } } // namespace v8::internal |
2169 | 2332 |
2170 #endif // V8_CODE_STUBS_H_ | 2333 #endif // V8_CODE_STUBS_H_ |
OLD | NEW |