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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 V(InternalArrayNoArgumentConstructor) \ | 83 V(InternalArrayNoArgumentConstructor) \ |
84 V(InternalArraySingleArgumentConstructor) \ | 84 V(InternalArraySingleArgumentConstructor) \ |
85 V(InternalArrayNArgumentsConstructor) \ | 85 V(InternalArrayNArgumentsConstructor) \ |
86 V(KeyedStoreElement) \ | 86 V(KeyedStoreElement) \ |
87 V(DebuggerStatement) \ | 87 V(DebuggerStatement) \ |
88 V(NameDictionaryLookup) \ | 88 V(NameDictionaryLookup) \ |
89 V(ElementsTransitionAndStore) \ | 89 V(ElementsTransitionAndStore) \ |
90 V(TransitionElementsKind) \ | 90 V(TransitionElementsKind) \ |
91 V(StoreArrayLiteralElement) \ | 91 V(StoreArrayLiteralElement) \ |
92 V(StubFailureTrampoline) \ | 92 V(StubFailureTrampoline) \ |
93 V(StubFailureTailCallTrampoline) \ | |
94 V(ArrayConstructor) \ | 93 V(ArrayConstructor) \ |
95 V(InternalArrayConstructor) \ | 94 V(InternalArrayConstructor) \ |
96 V(ProfileEntryHook) \ | 95 V(ProfileEntryHook) \ |
97 V(StoreGlobal) \ | 96 V(StoreGlobal) \ |
98 V(CallApiFunction) \ | 97 V(CallApiFunction) \ |
| 98 V(CallApiGetter) \ |
99 /* IC Handler stubs */ \ | 99 /* IC Handler stubs */ \ |
100 V(LoadField) \ | 100 V(LoadField) \ |
101 V(KeyedLoadField) \ | 101 V(KeyedLoadField) |
102 V(KeyedArrayCall) | |
103 | 102 |
104 // List of code stubs only used on ARM platforms. | 103 // List of code stubs only used on ARM platforms. |
105 #if V8_TARGET_ARCH_ARM | 104 #if V8_TARGET_ARCH_ARM |
106 #define CODE_STUB_LIST_ARM(V) \ | 105 #define CODE_STUB_LIST_ARM(V) \ |
107 V(GetProperty) \ | 106 V(GetProperty) \ |
108 V(SetProperty) \ | 107 V(SetProperty) \ |
109 V(InvokeBuiltin) \ | 108 V(InvokeBuiltin) \ |
110 V(DirectCEntry) | 109 V(DirectCEntry) |
111 #elif V8_TARGET_ARCH_A64 | 110 #elif V8_TARGET_ARCH_A64 |
112 #define CODE_STUB_LIST_ARM(V) \ | 111 #define CODE_STUB_LIST_ARM(V) \ |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 // Gets the major key from a code object that is a code stub or binary op IC. | 161 // Gets the major key from a code object that is a code stub or binary op IC. |
163 static Major GetMajorKey(Code* code_stub) { | 162 static Major GetMajorKey(Code* code_stub) { |
164 return static_cast<Major>(code_stub->major_key()); | 163 return static_cast<Major>(code_stub->major_key()); |
165 } | 164 } |
166 | 165 |
167 static const char* MajorName(Major major_key, bool allow_unknown_keys); | 166 static const char* MajorName(Major major_key, bool allow_unknown_keys); |
168 | 167 |
169 virtual ~CodeStub() {} | 168 virtual ~CodeStub() {} |
170 | 169 |
171 static void GenerateStubsAheadOfTime(Isolate* isolate); | 170 static void GenerateStubsAheadOfTime(Isolate* isolate); |
172 static void GenerateStubsRequiringBuiltinsAheadOfTime(Isolate* isolate); | |
173 static void GenerateFPStubs(Isolate* isolate); | 171 static void GenerateFPStubs(Isolate* isolate); |
174 | 172 |
175 // Some stubs put untagged junk on the stack that cannot be scanned by the | 173 // Some stubs put untagged junk on the stack that cannot be scanned by the |
176 // GC. This means that we must be statically sure that no GC can occur while | 174 // GC. This means that we must be statically sure that no GC can occur while |
177 // they are running. If that is the case they should override this to return | 175 // they are running. If that is the case they should override this to return |
178 // true, which will cause an assertion if we try to call something that can | 176 // true, which will cause an assertion if we try to call something that can |
179 // GC or if we try to put a stack frame on top of the junk, which would not | 177 // GC or if we try to put a stack frame on top of the junk, which would not |
180 // result in a traversable stack. | 178 // result in a traversable stack. |
181 virtual bool SometimesSetsUpAFrame() { return true; } | 179 virtual bool SometimesSetsUpAFrame() { return true; } |
182 | 180 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 | 271 |
274 protected: | 272 protected: |
275 // Generates the assembler code for the stub. | 273 // Generates the assembler code for the stub. |
276 virtual void Generate(MacroAssembler* masm) = 0; | 274 virtual void Generate(MacroAssembler* masm) = 0; |
277 }; | 275 }; |
278 | 276 |
279 | 277 |
280 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; | 278 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; |
281 enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; | 279 enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; |
282 | 280 |
283 enum ContinuationType { NORMAL_CONTINUATION, TAIL_CALL_CONTINUATION }; | |
284 | |
285 | |
286 struct CodeStubInterfaceDescriptor { | 281 struct CodeStubInterfaceDescriptor { |
287 CodeStubInterfaceDescriptor(); | 282 CodeStubInterfaceDescriptor(); |
288 int register_param_count_; | 283 int register_param_count_; |
289 | 284 |
290 Register stack_parameter_count_; | 285 Register stack_parameter_count_; |
291 // if hint_stack_parameter_count_ > 0, the code stub can optimize the | 286 // if hint_stack_parameter_count_ > 0, the code stub can optimize the |
292 // return sequence. Default value is -1, which means it is ignored. | 287 // return sequence. Default value is -1, which means it is ignored. |
293 int hint_stack_parameter_count_; | 288 int hint_stack_parameter_count_; |
294 ContinuationType continuation_type_; | |
295 StubFunctionMode function_mode_; | 289 StubFunctionMode function_mode_; |
296 Register* register_params_; | 290 Register* register_params_; |
297 | 291 |
298 Address deoptimization_handler_; | 292 Address deoptimization_handler_; |
299 HandlerArgumentsMode handler_arguments_mode_; | 293 HandlerArgumentsMode handler_arguments_mode_; |
300 | 294 |
301 bool initialized() const { return register_param_count_ >= 0; } | 295 bool initialized() const { return register_param_count_ >= 0; } |
302 | 296 |
303 bool HasTailCallContinuation() const { | |
304 return continuation_type_ == TAIL_CALL_CONTINUATION; | |
305 } | |
306 | |
307 int environment_length() const { | 297 int environment_length() const { |
308 return register_param_count_; | 298 return register_param_count_; |
309 } | 299 } |
310 | 300 |
311 void SetMissHandler(ExternalReference handler) { | 301 void SetMissHandler(ExternalReference handler) { |
312 miss_handler_ = handler; | 302 miss_handler_ = handler; |
313 has_miss_handler_ = true; | 303 has_miss_handler_ = true; |
314 // Our miss handler infrastructure doesn't currently support | 304 // Our miss handler infrastructure doesn't currently support |
315 // variable stack parameter counts. | 305 // variable stack parameter counts. |
316 ASSERT(!stack_parameter_count_.is_valid()); | 306 ASSERT(!stack_parameter_count_.is_valid()); |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1045 class RestoreContextBits: public BitField<bool, 0, 1> {}; | 1035 class RestoreContextBits: public BitField<bool, 0, 1> {}; |
1046 class CallDataUndefinedBits: public BitField<bool, 1, 1> {}; | 1036 class CallDataUndefinedBits: public BitField<bool, 1, 1> {}; |
1047 class ArgumentBits: public BitField<int, 2, Code::kArgumentsBits> {}; | 1037 class ArgumentBits: public BitField<int, 2, Code::kArgumentsBits> {}; |
1048 | 1038 |
1049 int bit_field_; | 1039 int bit_field_; |
1050 | 1040 |
1051 DISALLOW_COPY_AND_ASSIGN(CallApiFunctionStub); | 1041 DISALLOW_COPY_AND_ASSIGN(CallApiFunctionStub); |
1052 }; | 1042 }; |
1053 | 1043 |
1054 | 1044 |
| 1045 class CallApiGetterStub : public PlatformCodeStub { |
| 1046 public: |
| 1047 CallApiGetterStub() {} |
| 1048 |
| 1049 private: |
| 1050 virtual void Generate(MacroAssembler* masm) V8_OVERRIDE; |
| 1051 virtual Major MajorKey() V8_OVERRIDE { return CallApiGetter; } |
| 1052 virtual int MinorKey() V8_OVERRIDE { return 0; } |
| 1053 |
| 1054 DISALLOW_COPY_AND_ASSIGN(CallApiGetterStub); |
| 1055 }; |
| 1056 |
| 1057 |
1055 class KeyedLoadFieldStub: public LoadFieldStub { | 1058 class KeyedLoadFieldStub: public LoadFieldStub { |
1056 public: | 1059 public: |
1057 KeyedLoadFieldStub(bool inobject, int index, Representation representation) | 1060 KeyedLoadFieldStub(bool inobject, int index, Representation representation) |
1058 : LoadFieldStub() { | 1061 : LoadFieldStub() { |
1059 Initialize(Code::KEYED_LOAD_IC, inobject, index, representation); | 1062 Initialize(Code::KEYED_LOAD_IC, inobject, index, representation); |
1060 } | 1063 } |
1061 | 1064 |
1062 virtual void InitializeInterfaceDescriptor( | 1065 virtual void InitializeInterfaceDescriptor( |
1063 Isolate* isolate, | |
1064 CodeStubInterfaceDescriptor* descriptor); | |
1065 | |
1066 virtual Handle<Code> GenerateCode(Isolate* isolate); | |
1067 | |
1068 private: | |
1069 virtual CodeStub::Major MajorKey() { return KeyedLoadField; } | |
1070 }; | |
1071 | |
1072 | |
1073 class KeyedArrayCallStub: public HICStub { | |
1074 public: | |
1075 KeyedArrayCallStub(bool holey, int argc) : HICStub(), argc_(argc) { | |
1076 bit_field_ = HoleyBits::encode(holey); | |
1077 } | |
1078 | |
1079 virtual Code::Kind kind() const { return Code::KEYED_CALL_IC; } | |
1080 virtual ExtraICState GetExtraICState() { return bit_field_; } | |
1081 | |
1082 ElementsKind elements_kind() { | |
1083 return HoleyBits::decode(bit_field_) ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; | |
1084 } | |
1085 | |
1086 int argc() { return argc_; } | |
1087 virtual int GetStubFlags() { return argc(); } | |
1088 | |
1089 static bool IsHoley(Handle<Code> code) { | |
1090 ExtraICState state = code->extra_ic_state(); | |
1091 return HoleyBits::decode(state); | |
1092 } | |
1093 | |
1094 virtual void InitializeInterfaceDescriptor( | |
1095 Isolate* isolate, | 1066 Isolate* isolate, |
1096 CodeStubInterfaceDescriptor* descriptor); | 1067 CodeStubInterfaceDescriptor* descriptor); |
1097 | 1068 |
1098 virtual Handle<Code> GenerateCode(Isolate* isolate); | 1069 virtual Handle<Code> GenerateCode(Isolate* isolate); |
1099 | 1070 |
1100 private: | 1071 private: |
1101 virtual int NotMissMinorKey() { | 1072 virtual CodeStub::Major MajorKey() { return KeyedLoadField; } |
1102 return GetExtraICState() | ArgcBits::encode(argc_); | |
1103 } | |
1104 | |
1105 class HoleyBits: public BitField<bool, 0, 1> {}; | |
1106 STATIC_ASSERT(Code::kArgumentsBits <= kStubMinorKeyBits - 1); | |
1107 class ArgcBits: public BitField<int, 1, Code::kArgumentsBits> {}; | |
1108 virtual CodeStub::Major MajorKey() { return KeyedArrayCall; } | |
1109 int bit_field_; | |
1110 int argc_; | |
1111 }; | 1073 }; |
1112 | 1074 |
1113 | 1075 |
1114 class BinaryOpICStub : public HydrogenCodeStub { | 1076 class BinaryOpICStub : public HydrogenCodeStub { |
1115 public: | 1077 public: |
1116 BinaryOpICStub(Token::Value op, OverwriteMode mode) | 1078 BinaryOpICStub(Token::Value op, OverwriteMode mode) |
1117 : HydrogenCodeStub(UNINITIALIZED), state_(op, mode) {} | 1079 : HydrogenCodeStub(UNINITIALIZED), state_(op, mode) {} |
1118 | 1080 |
1119 explicit BinaryOpICStub(const BinaryOpIC::State& state) : state_(state) {} | 1081 explicit BinaryOpICStub(const BinaryOpIC::State& state) : state_(state) {} |
1120 | 1082 |
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1641 return ArgcBits::decode(minor_key); | 1603 return ArgcBits::decode(minor_key); |
1642 } | 1604 } |
1643 | 1605 |
1644 private: | 1606 private: |
1645 int argc_; | 1607 int argc_; |
1646 CallFunctionFlags flags_; | 1608 CallFunctionFlags flags_; |
1647 | 1609 |
1648 virtual void PrintName(StringStream* stream); | 1610 virtual void PrintName(StringStream* stream); |
1649 | 1611 |
1650 // Minor key encoding in 32 bits with Bitfield <Type, shift, size>. | 1612 // Minor key encoding in 32 bits with Bitfield <Type, shift, size>. |
1651 class FlagBits: public BitField<CallFunctionFlags, 0, 1> {}; | 1613 class FlagBits: public BitField<CallFunctionFlags, 0, 2> {}; |
1652 class ArgcBits: public BitField<unsigned, 1, 32 - 1> {}; | 1614 class ArgcBits: public BitField<unsigned, 2, 32 - 2> {}; |
1653 | 1615 |
1654 Major MajorKey() { return CallFunction; } | 1616 Major MajorKey() { return CallFunction; } |
1655 int MinorKey() { | 1617 int MinorKey() { |
1656 // Encode the parameters in a unique 32 bit value. | 1618 // Encode the parameters in a unique 32 bit value. |
1657 return FlagBits::encode(flags_) | ArgcBits::encode(argc_); | 1619 return FlagBits::encode(flags_) | ArgcBits::encode(argc_); |
1658 } | 1620 } |
1659 | 1621 |
1660 bool RecordCallTarget() { | 1622 bool RecordCallTarget() { |
1661 return (flags_ & RECORD_CALL_TARGET) != 0; | 1623 return flags_ == RECORD_CALL_TARGET; |
| 1624 } |
| 1625 |
| 1626 bool CallAsMethod() { |
| 1627 return flags_ == CALL_AS_METHOD || flags_ == WRAP_AND_CALL; |
| 1628 } |
| 1629 |
| 1630 bool NeedsChecks() { |
| 1631 return flags_ != WRAP_AND_CALL; |
1662 } | 1632 } |
1663 }; | 1633 }; |
1664 | 1634 |
1665 | 1635 |
1666 class CallConstructStub: public PlatformCodeStub { | 1636 class CallConstructStub: public PlatformCodeStub { |
1667 public: | 1637 public: |
1668 explicit CallConstructStub(CallFunctionFlags flags) : flags_(flags) {} | 1638 explicit CallConstructStub(CallFunctionFlags flags) : flags_(flags) {} |
1669 | 1639 |
1670 void Generate(MacroAssembler* masm); | 1640 void Generate(MacroAssembler* masm); |
1671 | 1641 |
1672 virtual void FinishCode(Handle<Code> code) { | 1642 virtual void FinishCode(Handle<Code> code) { |
1673 code->set_has_function_cache(RecordCallTarget()); | 1643 code->set_has_function_cache(RecordCallTarget()); |
1674 } | 1644 } |
1675 | 1645 |
1676 private: | 1646 private: |
1677 CallFunctionFlags flags_; | 1647 CallFunctionFlags flags_; |
1678 | 1648 |
1679 virtual void PrintName(StringStream* stream); | 1649 virtual void PrintName(StringStream* stream); |
1680 | 1650 |
1681 Major MajorKey() { return CallConstruct; } | 1651 Major MajorKey() { return CallConstruct; } |
1682 int MinorKey() { return flags_; } | 1652 int MinorKey() { return flags_; } |
1683 | 1653 |
1684 bool RecordCallTarget() { | 1654 bool RecordCallTarget() { |
1685 return (flags_ & RECORD_CALL_TARGET) != 0; | 1655 return (flags_ & RECORD_CALL_TARGET) != 0; |
1686 } | 1656 } |
| 1657 |
| 1658 bool CallAsMethod() { |
| 1659 return (flags_ & CALL_AS_METHOD) != 0; |
| 1660 } |
1687 }; | 1661 }; |
1688 | 1662 |
1689 | 1663 |
1690 enum StringIndexFlags { | 1664 enum StringIndexFlags { |
1691 // Accepts smis or heap numbers. | 1665 // Accepts smis or heap numbers. |
1692 STRING_INDEX_IS_NUMBER, | 1666 STRING_INDEX_IS_NUMBER, |
1693 | 1667 |
1694 // Accepts smis or heap numbers that are valid array indices | 1668 // Accepts smis or heap numbers that are valid array indices |
1695 // (ECMA-262 15.4). Invalid indices are reported as being out of | 1669 // (ECMA-262 15.4). Invalid indices are reported as being out of |
1696 // range. | 1670 // range. |
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2502 | 2476 |
2503 void Generate(MacroAssembler* masm); | 2477 void Generate(MacroAssembler* masm); |
2504 | 2478 |
2505 bool fp_registers_; | 2479 bool fp_registers_; |
2506 StubFunctionMode function_mode_; | 2480 StubFunctionMode function_mode_; |
2507 | 2481 |
2508 DISALLOW_COPY_AND_ASSIGN(StubFailureTrampolineStub); | 2482 DISALLOW_COPY_AND_ASSIGN(StubFailureTrampolineStub); |
2509 }; | 2483 }; |
2510 | 2484 |
2511 | 2485 |
2512 class StubFailureTailCallTrampolineStub : public PlatformCodeStub { | |
2513 public: | |
2514 StubFailureTailCallTrampolineStub() : fp_registers_(CanUseFPRegisters()) {} | |
2515 | |
2516 static void GenerateAheadOfTime(Isolate* isolate); | |
2517 | |
2518 private: | |
2519 class FPRegisters: public BitField<bool, 0, 1> {}; | |
2520 Major MajorKey() { return StubFailureTailCallTrampoline; } | |
2521 int MinorKey() { return FPRegisters::encode(fp_registers_); } | |
2522 | |
2523 void Generate(MacroAssembler* masm); | |
2524 | |
2525 bool fp_registers_; | |
2526 | |
2527 DISALLOW_COPY_AND_ASSIGN(StubFailureTailCallTrampolineStub); | |
2528 }; | |
2529 | |
2530 | |
2531 class ProfileEntryHookStub : public PlatformCodeStub { | 2486 class ProfileEntryHookStub : public PlatformCodeStub { |
2532 public: | 2487 public: |
2533 explicit ProfileEntryHookStub() {} | 2488 explicit ProfileEntryHookStub() {} |
2534 | 2489 |
2535 // The profile entry hook function is not allowed to cause a GC. | 2490 // The profile entry hook function is not allowed to cause a GC. |
2536 virtual bool SometimesSetsUpAFrame() { return false; } | 2491 virtual bool SometimesSetsUpAFrame() { return false; } |
2537 | 2492 |
2538 // Generates a call to the entry hook if it's enabled. | 2493 // Generates a call to the entry hook if it's enabled. |
2539 static void MaybeCallEntryHook(MacroAssembler* masm); | 2494 static void MaybeCallEntryHook(MacroAssembler* masm); |
2540 | 2495 |
(...skipping 12 matching lines...) Expand all Loading... |
2553 | 2508 |
2554 | 2509 |
2555 class CallDescriptors { | 2510 class CallDescriptors { |
2556 public: | 2511 public: |
2557 static void InitializeForIsolate(Isolate* isolate); | 2512 static void InitializeForIsolate(Isolate* isolate); |
2558 }; | 2513 }; |
2559 | 2514 |
2560 } } // namespace v8::internal | 2515 } } // namespace v8::internal |
2561 | 2516 |
2562 #endif // V8_CODE_STUBS_H_ | 2517 #endif // V8_CODE_STUBS_H_ |
OLD | NEW |