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 /* IC Handler stubs */ \ | 97 /* IC Handler stubs */ \ |
99 V(LoadField) \ | 98 V(LoadField) \ |
100 V(KeyedLoadField) \ | 99 V(KeyedLoadField) |
101 V(KeyedArrayCall) | |
102 | 100 |
103 // List of code stubs only used on ARM platforms. | 101 // List of code stubs only used on ARM platforms. |
104 #if V8_TARGET_ARCH_ARM | 102 #if V8_TARGET_ARCH_ARM |
105 #define CODE_STUB_LIST_ARM(V) \ | 103 #define CODE_STUB_LIST_ARM(V) \ |
106 V(GetProperty) \ | 104 V(GetProperty) \ |
107 V(SetProperty) \ | 105 V(SetProperty) \ |
108 V(InvokeBuiltin) \ | 106 V(InvokeBuiltin) \ |
109 V(DirectCEntry) | 107 V(DirectCEntry) |
110 #else | 108 #else |
111 #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... |
165 bool is_pregenerated = IsPregenerated(isolate); | 163 bool is_pregenerated = IsPregenerated(isolate); |
166 Code* code = NULL; | 164 Code* code = NULL; |
167 CHECK(!is_pregenerated || FindCodeInCache(&code, isolate)); | 165 CHECK(!is_pregenerated || FindCodeInCache(&code, isolate)); |
168 return is_pregenerated; | 166 return is_pregenerated; |
169 } | 167 } |
170 | 168 |
171 // See comment above, where Instanceof is defined. | 169 // See comment above, where Instanceof is defined. |
172 virtual bool IsPregenerated(Isolate* isolate) { return false; } | 170 virtual bool IsPregenerated(Isolate* isolate) { return false; } |
173 | 171 |
174 static void GenerateStubsAheadOfTime(Isolate* isolate); | 172 static void GenerateStubsAheadOfTime(Isolate* isolate); |
175 static void GenerateStubsRequiringBuiltinsAheadOfTime(Isolate* isolate); | |
176 static void GenerateFPStubs(Isolate* isolate); | 173 static void GenerateFPStubs(Isolate* isolate); |
177 | 174 |
178 // Some stubs put untagged junk on the stack that cannot be scanned by the | 175 // Some stubs put untagged junk on the stack that cannot be scanned by the |
179 // GC. This means that we must be statically sure that no GC can occur while | 176 // GC. This means that we must be statically sure that no GC can occur while |
180 // they are running. If that is the case they should override this to return | 177 // they are running. If that is the case they should override this to return |
181 // true, which will cause an assertion if we try to call something that can | 178 // true, which will cause an assertion if we try to call something that can |
182 // GC or if we try to put a stack frame on top of the junk, which would not | 179 // GC or if we try to put a stack frame on top of the junk, which would not |
183 // result in a traversable stack. | 180 // result in a traversable stack. |
184 virtual bool SometimesSetsUpAFrame() { return true; } | 181 virtual bool SometimesSetsUpAFrame() { return true; } |
185 | 182 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 | 272 |
276 protected: | 273 protected: |
277 // Generates the assembler code for the stub. | 274 // Generates the assembler code for the stub. |
278 virtual void Generate(MacroAssembler* masm) = 0; | 275 virtual void Generate(MacroAssembler* masm) = 0; |
279 }; | 276 }; |
280 | 277 |
281 | 278 |
282 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; | 279 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; |
283 enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; | 280 enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; |
284 | 281 |
285 enum ContinuationType { NORMAL_CONTINUATION, TAIL_CALL_CONTINUATION }; | |
286 | |
287 | |
288 struct CodeStubInterfaceDescriptor { | 282 struct CodeStubInterfaceDescriptor { |
289 CodeStubInterfaceDescriptor(); | 283 CodeStubInterfaceDescriptor(); |
290 int register_param_count_; | 284 int register_param_count_; |
291 | 285 |
292 Register stack_parameter_count_; | 286 Register stack_parameter_count_; |
293 // if hint_stack_parameter_count_ > 0, the code stub can optimize the | 287 // if hint_stack_parameter_count_ > 0, the code stub can optimize the |
294 // return sequence. Default value is -1, which means it is ignored. | 288 // return sequence. Default value is -1, which means it is ignored. |
295 int hint_stack_parameter_count_; | 289 int hint_stack_parameter_count_; |
296 ContinuationType continuation_type_; | |
297 StubFunctionMode function_mode_; | 290 StubFunctionMode function_mode_; |
298 Register* register_params_; | 291 Register* register_params_; |
299 | 292 |
300 Address deoptimization_handler_; | 293 Address deoptimization_handler_; |
301 HandlerArgumentsMode handler_arguments_mode_; | 294 HandlerArgumentsMode handler_arguments_mode_; |
302 | 295 |
303 bool initialized() const { return register_param_count_ >= 0; } | |
304 | |
305 bool HasTailCallContinuation() const { | |
306 return continuation_type_ == TAIL_CALL_CONTINUATION; | |
307 } | |
308 | |
309 int environment_length() const { | 296 int environment_length() const { |
310 return register_param_count_; | 297 return register_param_count_; |
311 } | 298 } |
312 | 299 |
| 300 bool initialized() const { return register_param_count_ >= 0; } |
| 301 |
313 void SetMissHandler(ExternalReference handler) { | 302 void SetMissHandler(ExternalReference handler) { |
314 miss_handler_ = handler; | 303 miss_handler_ = handler; |
315 has_miss_handler_ = true; | 304 has_miss_handler_ = true; |
316 // Our miss handler infrastructure doesn't currently support | 305 // Our miss handler infrastructure doesn't currently support |
317 // variable stack parameter counts. | 306 // variable stack parameter counts. |
318 ASSERT(!stack_parameter_count_.is_valid()); | 307 ASSERT(!stack_parameter_count_.is_valid()); |
319 } | 308 } |
320 | 309 |
321 ExternalReference miss_handler() { | 310 ExternalReference miss_handler() { |
322 ASSERT(has_miss_handler_); | 311 ASSERT(has_miss_handler_); |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 protected: | 869 protected: |
881 class KindBits: public BitField<Code::Kind, 0, 4> {}; | 870 class KindBits: public BitField<Code::Kind, 0, 4> {}; |
882 virtual Code::Kind kind() const = 0; | 871 virtual Code::Kind kind() const = 0; |
883 }; | 872 }; |
884 | 873 |
885 | 874 |
886 class HandlerStub: public HICStub { | 875 class HandlerStub: public HICStub { |
887 public: | 876 public: |
888 virtual Code::Kind GetCodeKind() const { return Code::HANDLER; } | 877 virtual Code::Kind GetCodeKind() const { return Code::HANDLER; } |
889 virtual int GetStubFlags() { return kind(); } | 878 virtual int GetStubFlags() { return kind(); } |
890 | |
891 protected: | |
892 HandlerStub() : HICStub() { } | |
893 virtual int NotMissMinorKey() { return bit_field_; } | |
894 int bit_field_; | |
895 }; | 879 }; |
896 | 880 |
897 | 881 |
898 class LoadFieldStub: public HandlerStub { | 882 class LoadFieldStub: public HandlerStub { |
899 public: | 883 public: |
900 LoadFieldStub(bool inobject, int index, Representation representation) { | 884 LoadFieldStub(bool inobject, int index, Representation representation) { |
901 Initialize(Code::LOAD_IC, inobject, index, representation); | 885 Initialize(Code::LOAD_IC, inobject, index, representation); |
902 } | 886 } |
903 | 887 |
904 virtual Handle<Code> GenerateCode(Isolate* isolate); | 888 virtual Handle<Code> GenerateCode(Isolate* isolate); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 | IndexBits::encode(index) | 930 | IndexBits::encode(index) |
947 | UnboxedDoubleBits::encode(unboxed_double); | 931 | UnboxedDoubleBits::encode(unboxed_double); |
948 } | 932 } |
949 | 933 |
950 private: | 934 private: |
951 STATIC_ASSERT(KindBits::kSize == 4); | 935 STATIC_ASSERT(KindBits::kSize == 4); |
952 class InobjectBits: public BitField<bool, 4, 1> {}; | 936 class InobjectBits: public BitField<bool, 4, 1> {}; |
953 class IndexBits: public BitField<int, 5, 11> {}; | 937 class IndexBits: public BitField<int, 5, 11> {}; |
954 class UnboxedDoubleBits: public BitField<bool, 16, 1> {}; | 938 class UnboxedDoubleBits: public BitField<bool, 16, 1> {}; |
955 virtual CodeStub::Major MajorKey() { return LoadField; } | 939 virtual CodeStub::Major MajorKey() { return LoadField; } |
| 940 virtual int NotMissMinorKey() { return bit_field_; } |
| 941 |
| 942 int bit_field_; |
956 }; | 943 }; |
957 | 944 |
958 | 945 |
959 class StoreGlobalStub : public HandlerStub { | 946 class StoreGlobalStub : public HandlerStub { |
960 public: | 947 public: |
961 StoreGlobalStub(StrictModeFlag strict_mode, bool is_constant) { | 948 StoreGlobalStub(StrictModeFlag strict_mode, bool is_constant) { |
962 bit_field_ = StrictModeBits::encode(strict_mode) | | 949 bit_field_ = StrictModeBits::encode(strict_mode) | |
963 IsConstantBits::encode(is_constant); | 950 IsConstantBits::encode(is_constant); |
964 } | 951 } |
965 | 952 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1024 Isolate* isolate, | 1011 Isolate* isolate, |
1025 CodeStubInterfaceDescriptor* descriptor); | 1012 CodeStubInterfaceDescriptor* descriptor); |
1026 | 1013 |
1027 virtual Handle<Code> GenerateCode(Isolate* isolate); | 1014 virtual Handle<Code> GenerateCode(Isolate* isolate); |
1028 | 1015 |
1029 private: | 1016 private: |
1030 virtual CodeStub::Major MajorKey() { return KeyedLoadField; } | 1017 virtual CodeStub::Major MajorKey() { return KeyedLoadField; } |
1031 }; | 1018 }; |
1032 | 1019 |
1033 | 1020 |
1034 class KeyedArrayCallStub: public HICStub { | |
1035 public: | |
1036 KeyedArrayCallStub(bool holey, int argc) : HICStub(), argc_(argc) { | |
1037 bit_field_ = KindBits::encode(Code::KEYED_CALL_IC) | |
1038 | HoleyBits::encode(holey); | |
1039 } | |
1040 | |
1041 virtual Code::Kind kind() const { | |
1042 return KindBits::decode(bit_field_); | |
1043 } | |
1044 | |
1045 virtual Code::ExtraICState GetExtraICState() { return bit_field_; } | |
1046 | |
1047 ElementsKind elements_kind() { | |
1048 return HoleyBits::decode(bit_field_) ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; | |
1049 } | |
1050 | |
1051 int argc() { return argc_; } | |
1052 virtual int GetStubFlags() { return argc(); } | |
1053 | |
1054 static bool IsHoley(Handle<Code> code) { | |
1055 Code::ExtraICState state = code->extra_ic_state(); | |
1056 return HoleyBits::decode(state); | |
1057 } | |
1058 | |
1059 virtual void InitializeInterfaceDescriptor( | |
1060 Isolate* isolate, | |
1061 CodeStubInterfaceDescriptor* descriptor); | |
1062 | |
1063 virtual Handle<Code> GenerateCode(Isolate* isolate); | |
1064 | |
1065 private: | |
1066 virtual int NotMissMinorKey() { | |
1067 return GetExtraICState() | ArgcBits::encode(argc_); | |
1068 } | |
1069 | |
1070 STATIC_ASSERT(KindBits::kSize == 4); | |
1071 class HoleyBits: public BitField<bool, 4, 1> {}; | |
1072 STATIC_ASSERT(Code::kArgumentsBits <= kStubMinorKeyBits - 5); | |
1073 class ArgcBits: public BitField<int, 5, Code::kArgumentsBits> {}; | |
1074 virtual CodeStub::Major MajorKey() { return KeyedArrayCall; } | |
1075 int bit_field_; | |
1076 int argc_; | |
1077 }; | |
1078 | |
1079 | |
1080 class BinaryOpStub: public HydrogenCodeStub { | 1021 class BinaryOpStub: public HydrogenCodeStub { |
1081 public: | 1022 public: |
1082 BinaryOpStub(Token::Value op, OverwriteMode mode) | 1023 BinaryOpStub(Token::Value op, OverwriteMode mode) |
1083 : HydrogenCodeStub(UNINITIALIZED), op_(op), mode_(mode) { | 1024 : HydrogenCodeStub(UNINITIALIZED), op_(op), mode_(mode) { |
1084 ASSERT(op <= LAST_TOKEN && op >= FIRST_TOKEN); | 1025 ASSERT(op <= LAST_TOKEN && op >= FIRST_TOKEN); |
1085 Initialize(); | 1026 Initialize(); |
1086 } | 1027 } |
1087 | 1028 |
1088 explicit BinaryOpStub(Code::ExtraICState state) | 1029 explicit BinaryOpStub(Code::ExtraICState state) |
1089 : op_(decode_token(OpBits::decode(state))), | 1030 : op_(decode_token(OpBits::decode(state))), |
(...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2451 | 2392 |
2452 void Generate(MacroAssembler* masm); | 2393 void Generate(MacroAssembler* masm); |
2453 | 2394 |
2454 bool fp_registers_; | 2395 bool fp_registers_; |
2455 StubFunctionMode function_mode_; | 2396 StubFunctionMode function_mode_; |
2456 | 2397 |
2457 DISALLOW_COPY_AND_ASSIGN(StubFailureTrampolineStub); | 2398 DISALLOW_COPY_AND_ASSIGN(StubFailureTrampolineStub); |
2458 }; | 2399 }; |
2459 | 2400 |
2460 | 2401 |
2461 class StubFailureTailCallTrampolineStub : public PlatformCodeStub { | |
2462 public: | |
2463 StubFailureTailCallTrampolineStub() : fp_registers_(CanUseFPRegisters()) {} | |
2464 | |
2465 virtual bool IsPregenerated(Isolate* isolate) V8_OVERRIDE { return true; } | |
2466 | |
2467 static void GenerateAheadOfTime(Isolate* isolate); | |
2468 | |
2469 private: | |
2470 class FPRegisters: public BitField<bool, 0, 1> {}; | |
2471 Major MajorKey() { return StubFailureTailCallTrampoline; } | |
2472 int MinorKey() { return FPRegisters::encode(fp_registers_); } | |
2473 | |
2474 void Generate(MacroAssembler* masm); | |
2475 | |
2476 bool fp_registers_; | |
2477 | |
2478 DISALLOW_COPY_AND_ASSIGN(StubFailureTailCallTrampolineStub); | |
2479 }; | |
2480 | |
2481 | |
2482 class ProfileEntryHookStub : public PlatformCodeStub { | 2402 class ProfileEntryHookStub : public PlatformCodeStub { |
2483 public: | 2403 public: |
2484 explicit ProfileEntryHookStub() {} | 2404 explicit ProfileEntryHookStub() {} |
2485 | 2405 |
2486 // The profile entry hook function is not allowed to cause a GC. | 2406 // The profile entry hook function is not allowed to cause a GC. |
2487 virtual bool SometimesSetsUpAFrame() { return false; } | 2407 virtual bool SometimesSetsUpAFrame() { return false; } |
2488 | 2408 |
2489 // Generates a call to the entry hook if it's enabled. | 2409 // Generates a call to the entry hook if it's enabled. |
2490 static void MaybeCallEntryHook(MacroAssembler* masm); | 2410 static void MaybeCallEntryHook(MacroAssembler* masm); |
2491 | 2411 |
2492 private: | 2412 private: |
2493 static void EntryHookTrampoline(intptr_t function, | 2413 static void EntryHookTrampoline(intptr_t function, |
2494 intptr_t stack_pointer, | 2414 intptr_t stack_pointer, |
2495 Isolate* isolate); | 2415 Isolate* isolate); |
2496 | 2416 |
2497 Major MajorKey() { return ProfileEntryHook; } | 2417 Major MajorKey() { return ProfileEntryHook; } |
2498 int MinorKey() { return 0; } | 2418 int MinorKey() { return 0; } |
2499 | 2419 |
2500 void Generate(MacroAssembler* masm); | 2420 void Generate(MacroAssembler* masm); |
2501 | 2421 |
2502 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); | 2422 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); |
2503 }; | 2423 }; |
2504 | 2424 |
2505 } } // namespace v8::internal | 2425 } } // namespace v8::internal |
2506 | 2426 |
2507 #endif // V8_CODE_STUBS_H_ | 2427 #endif // V8_CODE_STUBS_H_ |
OLD | NEW |