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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 V(InternalArrayNoArgumentConstructor) \ | 81 V(InternalArrayNoArgumentConstructor) \ |
82 V(InternalArraySingleArgumentConstructor) \ | 82 V(InternalArraySingleArgumentConstructor) \ |
83 V(InternalArrayNArgumentsConstructor) \ | 83 V(InternalArrayNArgumentsConstructor) \ |
84 V(KeyedStoreElement) \ | 84 V(KeyedStoreElement) \ |
85 V(DebuggerStatement) \ | 85 V(DebuggerStatement) \ |
86 V(NameDictionaryLookup) \ | 86 V(NameDictionaryLookup) \ |
87 V(ElementsTransitionAndStore) \ | 87 V(ElementsTransitionAndStore) \ |
88 V(TransitionElementsKind) \ | 88 V(TransitionElementsKind) \ |
89 V(StoreArrayLiteralElement) \ | 89 V(StoreArrayLiteralElement) \ |
90 V(StubFailureTrampoline) \ | 90 V(StubFailureTrampoline) \ |
91 V(CallStubFailureTrampoline) \ | |
91 V(ArrayConstructor) \ | 92 V(ArrayConstructor) \ |
92 V(InternalArrayConstructor) \ | 93 V(InternalArrayConstructor) \ |
93 V(ProfileEntryHook) \ | 94 V(ProfileEntryHook) \ |
94 V(StoreGlobal) \ | 95 V(StoreGlobal) \ |
95 /* IC Handler stubs */ \ | 96 /* IC Handler stubs */ \ |
96 V(LoadField) \ | 97 V(LoadField) \ |
97 V(KeyedLoadField) | 98 V(KeyedLoadField) \ |
99 V(KeyedArrayCall) | |
98 | 100 |
99 // List of code stubs only used on ARM platforms. | 101 // List of code stubs only used on ARM platforms. |
100 #if V8_TARGET_ARCH_ARM | 102 #if V8_TARGET_ARCH_ARM |
101 #define CODE_STUB_LIST_ARM(V) \ | 103 #define CODE_STUB_LIST_ARM(V) \ |
102 V(GetProperty) \ | 104 V(GetProperty) \ |
103 V(SetProperty) \ | 105 V(SetProperty) \ |
104 V(InvokeBuiltin) \ | 106 V(InvokeBuiltin) \ |
105 V(DirectCEntry) | 107 V(DirectCEntry) |
106 #else | 108 #else |
107 #define CODE_STUB_LIST_ARM(V) | 109 #define CODE_STUB_LIST_ARM(V) |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
161 bool is_pregenerated = IsPregenerated(isolate); | 163 bool is_pregenerated = IsPregenerated(isolate); |
162 Code* code = NULL; | 164 Code* code = NULL; |
163 CHECK(!is_pregenerated || FindCodeInCache(&code, isolate)); | 165 CHECK(!is_pregenerated || FindCodeInCache(&code, isolate)); |
164 return is_pregenerated; | 166 return is_pregenerated; |
165 } | 167 } |
166 | 168 |
167 // See comment above, where Instanceof is defined. | 169 // See comment above, where Instanceof is defined. |
168 virtual bool IsPregenerated(Isolate* isolate) { return false; } | 170 virtual bool IsPregenerated(Isolate* isolate) { return false; } |
169 | 171 |
170 static void GenerateStubsAheadOfTime(Isolate* isolate); | 172 static void GenerateStubsAheadOfTime(Isolate* isolate); |
173 static void GenerateStubsRequiringBuiltinsAheadOfTime(Isolate* isolate); | |
171 static void GenerateFPStubs(Isolate* isolate); | 174 static void GenerateFPStubs(Isolate* isolate); |
172 | 175 |
173 // Some stubs put untagged junk on the stack that cannot be scanned by the | 176 // Some stubs put untagged junk on the stack that cannot be scanned by the |
174 // GC. This means that we must be statically sure that no GC can occur while | 177 // GC. This means that we must be statically sure that no GC can occur while |
175 // they are running. If that is the case they should override this to return | 178 // they are running. If that is the case they should override this to return |
176 // true, which will cause an assertion if we try to call something that can | 179 // true, which will cause an assertion if we try to call something that can |
177 // GC or if we try to put a stack frame on top of the junk, which would not | 180 // GC or if we try to put a stack frame on top of the junk, which would not |
178 // result in a traversable stack. | 181 // result in a traversable stack. |
179 virtual bool SometimesSetsUpAFrame() { return true; } | 182 virtual bool SometimesSetsUpAFrame() { return true; } |
180 | 183 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
275 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; | 278 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; |
276 | 279 |
277 | 280 |
278 struct CodeStubInterfaceDescriptor { | 281 struct CodeStubInterfaceDescriptor { |
279 CodeStubInterfaceDescriptor(); | 282 CodeStubInterfaceDescriptor(); |
280 int register_param_count_; | 283 int register_param_count_; |
281 const Register* stack_parameter_count_; | 284 const Register* stack_parameter_count_; |
282 // if hint_stack_parameter_count_ > 0, the code stub can optimize the | 285 // if hint_stack_parameter_count_ > 0, the code stub can optimize the |
283 // return sequence. Default value is -1, which means it is ignored. | 286 // return sequence. Default value is -1, which means it is ignored. |
284 int hint_stack_parameter_count_; | 287 int hint_stack_parameter_count_; |
288 bool call_stub_; | |
285 StubFunctionMode function_mode_; | 289 StubFunctionMode function_mode_; |
286 Register* register_params_; | 290 Register* register_params_; |
287 Address deoptimization_handler_; | 291 Address deoptimization_handler_; |
288 | 292 |
289 int environment_length() const { | 293 int environment_length() const { |
290 if (stack_parameter_count_ != NULL) { | 294 if (stack_parameter_count_ != NULL) { |
291 return register_param_count_ + 1; | 295 return register_param_count_ + 1; |
292 } | 296 } |
293 return register_param_count_; | 297 return register_param_count_; |
294 } | 298 } |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
902 }; | 906 }; |
903 | 907 |
904 | 908 |
905 class HandlerStub: public HICStub { | 909 class HandlerStub: public HICStub { |
906 public: | 910 public: |
907 virtual Code::Kind GetCodeKind() const { return Code::STUB; } | 911 virtual Code::Kind GetCodeKind() const { return Code::STUB; } |
908 virtual int GetStubFlags() { return kind(); } | 912 virtual int GetStubFlags() { return kind(); } |
909 | 913 |
910 protected: | 914 protected: |
911 HandlerStub() : HICStub() { } | 915 HandlerStub() : HICStub() { } |
916 virtual int NotMissMinorKey() { return bit_field_; } | |
917 int bit_field_; | |
912 }; | 918 }; |
913 | 919 |
914 | 920 |
915 class LoadFieldStub: public HandlerStub { | 921 class LoadFieldStub: public HandlerStub { |
916 public: | 922 public: |
917 LoadFieldStub(bool inobject, int index, Representation representation) | 923 LoadFieldStub(bool inobject, int index, Representation representation) |
918 : HandlerStub() { | 924 : HandlerStub() { |
919 Initialize(Code::LOAD_IC, inobject, index, representation); | 925 Initialize(Code::LOAD_IC, inobject, index, representation); |
920 } | 926 } |
921 | 927 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
964 | IndexBits::encode(index) | 970 | IndexBits::encode(index) |
965 | UnboxedDoubleBits::encode(unboxed_double); | 971 | UnboxedDoubleBits::encode(unboxed_double); |
966 } | 972 } |
967 | 973 |
968 private: | 974 private: |
969 STATIC_ASSERT(KindBits::kSize == 4); | 975 STATIC_ASSERT(KindBits::kSize == 4); |
970 class InobjectBits: public BitField<bool, 4, 1> {}; | 976 class InobjectBits: public BitField<bool, 4, 1> {}; |
971 class IndexBits: public BitField<int, 5, 11> {}; | 977 class IndexBits: public BitField<int, 5, 11> {}; |
972 class UnboxedDoubleBits: public BitField<bool, 16, 1> {}; | 978 class UnboxedDoubleBits: public BitField<bool, 16, 1> {}; |
973 virtual CodeStub::Major MajorKey() { return LoadField; } | 979 virtual CodeStub::Major MajorKey() { return LoadField; } |
974 virtual int NotMissMinorKey() { return bit_field_; } | |
975 | |
976 int bit_field_; | |
977 }; | 980 }; |
978 | 981 |
979 | 982 |
980 class KeyedLoadFieldStub: public LoadFieldStub { | 983 class KeyedLoadFieldStub: public LoadFieldStub { |
981 public: | 984 public: |
982 KeyedLoadFieldStub(bool inobject, int index, Representation representation) | 985 KeyedLoadFieldStub(bool inobject, int index, Representation representation) |
983 : LoadFieldStub() { | 986 : LoadFieldStub() { |
984 Initialize(Code::KEYED_LOAD_IC, inobject, index, representation); | 987 Initialize(Code::KEYED_LOAD_IC, inobject, index, representation); |
985 } | 988 } |
986 | 989 |
987 virtual void InitializeInterfaceDescriptor( | 990 virtual void InitializeInterfaceDescriptor( |
988 Isolate* isolate, | 991 Isolate* isolate, |
989 CodeStubInterfaceDescriptor* descriptor); | 992 CodeStubInterfaceDescriptor* descriptor); |
990 | 993 |
991 virtual Handle<Code> GenerateCode(Isolate* isolate); | 994 virtual Handle<Code> GenerateCode(Isolate* isolate); |
992 | 995 |
993 private: | 996 private: |
994 virtual CodeStub::Major MajorKey() { return KeyedLoadField; } | 997 virtual CodeStub::Major MajorKey() { return KeyedLoadField; } |
995 }; | 998 }; |
996 | 999 |
997 | 1000 |
1001 class KeyedArrayCallStub: public HICStub { | |
1002 public: | |
1003 KeyedArrayCallStub(bool holey, int argc) : HICStub(), argc_(argc) { | |
1004 bit_field_ = KindBits::encode(Code::KEYED_CALL_IC) | |
1005 | HoleyBits::encode(holey); | |
1006 } | |
1007 | |
1008 virtual Code::Kind kind() const { | |
1009 return KindBits::decode(bit_field_); | |
1010 } | |
1011 | |
1012 virtual Code::ExtraICState GetExtraICState() { return bit_field_; } | |
1013 | |
1014 ElementsKind elements_kind() { | |
1015 return HoleyBits::decode(bit_field_) ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; | |
1016 } | |
1017 | |
1018 int argc() { return argc_; } | |
1019 virtual int GetStubFlags() { return argc(); } | |
1020 | |
1021 static bool IsHoley(Handle<Code> code) { | |
1022 Code::ExtraICState state = code->extra_ic_state(); | |
1023 return HoleyBits::decode(state); | |
1024 } | |
1025 | |
1026 virtual void InitializeInterfaceDescriptor( | |
1027 Isolate* isolate, | |
1028 CodeStubInterfaceDescriptor* descriptor); | |
1029 | |
1030 virtual Handle<Code> GenerateCode(Isolate* isolate); | |
1031 | |
1032 private: | |
1033 virtual int NotMissMinorKey() { | |
1034 return GetExtraICState() | ArgcBits::encode(argc_); | |
1035 } | |
1036 | |
1037 STATIC_ASSERT(KindBits::kSize == 4); | |
1038 class HoleyBits: public BitField<bool, 4, 1> {}; | |
1039 class ArgcBits: public BitField<int, 5, 20> {}; | |
danno
2013/10/02 08:49:11
Don't we have a constant somewhere with the number
Toon Verwaest
2013/10/02 16:28:16
Done.
| |
1040 virtual CodeStub::Major MajorKey() { return KeyedArrayCall; } | |
1041 int bit_field_; | |
1042 int argc_; | |
1043 }; | |
1044 | |
1045 | |
998 class BinaryOpStub: public PlatformCodeStub { | 1046 class BinaryOpStub: public PlatformCodeStub { |
999 public: | 1047 public: |
1000 BinaryOpStub(Token::Value op, OverwriteMode mode) | 1048 BinaryOpStub(Token::Value op, OverwriteMode mode) |
1001 : op_(op), | 1049 : op_(op), |
1002 mode_(mode), | 1050 mode_(mode), |
1003 platform_specific_bit_(false), | 1051 platform_specific_bit_(false), |
1004 left_type_(BinaryOpIC::UNINITIALIZED), | 1052 left_type_(BinaryOpIC::UNINITIALIZED), |
1005 right_type_(BinaryOpIC::UNINITIALIZED), | 1053 right_type_(BinaryOpIC::UNINITIALIZED), |
1006 result_type_(BinaryOpIC::UNINITIALIZED), | 1054 result_type_(BinaryOpIC::UNINITIALIZED), |
1007 encoded_right_arg_(false, encode_arg_value(1)) { | 1055 encoded_right_arg_(false, encode_arg_value(1)) { |
(...skipping 1285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2293 | 2341 |
2294 void Generate(MacroAssembler* masm); | 2342 void Generate(MacroAssembler* masm); |
2295 | 2343 |
2296 bool fp_registers_; | 2344 bool fp_registers_; |
2297 StubFunctionMode function_mode_; | 2345 StubFunctionMode function_mode_; |
2298 | 2346 |
2299 DISALLOW_COPY_AND_ASSIGN(StubFailureTrampolineStub); | 2347 DISALLOW_COPY_AND_ASSIGN(StubFailureTrampolineStub); |
2300 }; | 2348 }; |
2301 | 2349 |
2302 | 2350 |
2351 class CallStubFailureTrampolineStub : public PlatformCodeStub { | |
2352 public: | |
2353 CallStubFailureTrampolineStub() : fp_registers_(CanUseFPRegisters()) {} | |
2354 | |
2355 virtual bool IsPregenerated(Isolate* isolate) V8_OVERRIDE { return true; } | |
2356 | |
2357 static void GenerateAheadOfTime(Isolate* isolate); | |
2358 | |
2359 private: | |
2360 class FPRegisters: public BitField<bool, 0, 1> {}; | |
danno
2013/10/02 08:49:11
nit: crazy unnecessary spacing on the line above.
Toon Verwaest
2013/10/02 16:28:16
Done.
| |
2361 Major MajorKey() { return CallStubFailureTrampoline; } | |
2362 int MinorKey() { return FPRegisters::encode(fp_registers_); } | |
2363 | |
2364 void Generate(MacroAssembler* masm); | |
2365 | |
2366 bool fp_registers_; | |
2367 | |
2368 DISALLOW_COPY_AND_ASSIGN(CallStubFailureTrampolineStub); | |
2369 }; | |
2370 | |
2371 | |
2303 class ProfileEntryHookStub : public PlatformCodeStub { | 2372 class ProfileEntryHookStub : public PlatformCodeStub { |
2304 public: | 2373 public: |
2305 explicit ProfileEntryHookStub() {} | 2374 explicit ProfileEntryHookStub() {} |
2306 | 2375 |
2307 // The profile entry hook function is not allowed to cause a GC. | 2376 // The profile entry hook function is not allowed to cause a GC. |
2308 virtual bool SometimesSetsUpAFrame() { return false; } | 2377 virtual bool SometimesSetsUpAFrame() { return false; } |
2309 | 2378 |
2310 // Generates a call to the entry hook if it's enabled. | 2379 // Generates a call to the entry hook if it's enabled. |
2311 static void MaybeCallEntryHook(MacroAssembler* masm); | 2380 static void MaybeCallEntryHook(MacroAssembler* masm); |
2312 | 2381 |
2313 private: | 2382 private: |
2314 static void EntryHookTrampoline(intptr_t function, | 2383 static void EntryHookTrampoline(intptr_t function, |
2315 intptr_t stack_pointer, | 2384 intptr_t stack_pointer, |
2316 Isolate* isolate); | 2385 Isolate* isolate); |
2317 | 2386 |
2318 Major MajorKey() { return ProfileEntryHook; } | 2387 Major MajorKey() { return ProfileEntryHook; } |
2319 int MinorKey() { return 0; } | 2388 int MinorKey() { return 0; } |
2320 | 2389 |
2321 void Generate(MacroAssembler* masm); | 2390 void Generate(MacroAssembler* masm); |
2322 | 2391 |
2323 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); | 2392 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); |
2324 }; | 2393 }; |
2325 | 2394 |
2326 } } // namespace v8::internal | 2395 } } // namespace v8::internal |
2327 | 2396 |
2328 #endif // V8_CODE_STUBS_H_ | 2397 #endif // V8_CODE_STUBS_H_ |
OLD | NEW |