| 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(StubFailureTailCallTrampoline) \ |
| 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 | 271 |
| 269 protected: | 272 protected: |
| 270 // Generates the assembler code for the stub. | 273 // Generates the assembler code for the stub. |
| 271 virtual void Generate(MacroAssembler* masm) = 0; | 274 virtual void Generate(MacroAssembler* masm) = 0; |
| 272 }; | 275 }; |
| 273 | 276 |
| 274 | 277 |
| 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 |
| 281 enum ContinuationType { NORMAL_CONTINUATION, TAIL_CALL_CONTINUATION }; |
| 282 |
| 283 |
| 278 struct CodeStubInterfaceDescriptor { | 284 struct CodeStubInterfaceDescriptor { |
| 279 CodeStubInterfaceDescriptor(); | 285 CodeStubInterfaceDescriptor(); |
| 280 int register_param_count_; | 286 int register_param_count_; |
| 281 const Register* stack_parameter_count_; | 287 const Register* stack_parameter_count_; |
| 282 // if hint_stack_parameter_count_ > 0, the code stub can optimize the | 288 // if hint_stack_parameter_count_ > 0, the code stub can optimize the |
| 283 // return sequence. Default value is -1, which means it is ignored. | 289 // return sequence. Default value is -1, which means it is ignored. |
| 284 int hint_stack_parameter_count_; | 290 int hint_stack_parameter_count_; |
| 291 ContinuationType continuation_type_; |
| 285 StubFunctionMode function_mode_; | 292 StubFunctionMode function_mode_; |
| 286 Register* register_params_; | 293 Register* register_params_; |
| 287 Address deoptimization_handler_; | 294 Address deoptimization_handler_; |
| 288 | 295 |
| 289 int environment_length() const { | 296 int environment_length() const { |
| 290 if (stack_parameter_count_ != NULL) { | 297 if (stack_parameter_count_ != NULL) { |
| 291 return register_param_count_ + 1; | 298 return register_param_count_ + 1; |
| 292 } | 299 } |
| 293 return register_param_count_; | 300 return register_param_count_; |
| 294 } | 301 } |
| 295 | 302 |
| 296 bool initialized() const { return register_param_count_ >= 0; } | 303 bool initialized() const { return register_param_count_ >= 0; } |
| 297 | 304 |
| 305 bool HasTailCallContinuation() { |
| 306 return continuation_type_ == TAIL_CALL_CONTINUATION; |
| 307 } |
| 308 |
| 309 bool PassCallerArguments() { |
| 310 return stack_parameter_count_ != NULL || HasTailCallContinuation(); |
| 311 } |
| 312 |
| 298 void SetMissHandler(ExternalReference handler) { | 313 void SetMissHandler(ExternalReference handler) { |
| 299 miss_handler_ = handler; | 314 miss_handler_ = handler; |
| 300 has_miss_handler_ = true; | 315 has_miss_handler_ = true; |
| 301 } | 316 } |
| 302 | 317 |
| 303 ExternalReference miss_handler() { | 318 ExternalReference miss_handler() { |
| 304 ASSERT(has_miss_handler_); | 319 ASSERT(has_miss_handler_); |
| 305 return miss_handler_; | 320 return miss_handler_; |
| 306 } | 321 } |
| 307 | 322 |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 }; | 917 }; |
| 903 | 918 |
| 904 | 919 |
| 905 class HandlerStub: public HICStub { | 920 class HandlerStub: public HICStub { |
| 906 public: | 921 public: |
| 907 virtual Code::Kind GetCodeKind() const { return Code::STUB; } | 922 virtual Code::Kind GetCodeKind() const { return Code::STUB; } |
| 908 virtual int GetStubFlags() { return kind(); } | 923 virtual int GetStubFlags() { return kind(); } |
| 909 | 924 |
| 910 protected: | 925 protected: |
| 911 HandlerStub() : HICStub() { } | 926 HandlerStub() : HICStub() { } |
| 927 virtual int NotMissMinorKey() { return bit_field_; } |
| 928 int bit_field_; |
| 912 }; | 929 }; |
| 913 | 930 |
| 914 | 931 |
| 915 class LoadFieldStub: public HandlerStub { | 932 class LoadFieldStub: public HandlerStub { |
| 916 public: | 933 public: |
| 917 LoadFieldStub(bool inobject, int index, Representation representation) | 934 LoadFieldStub(bool inobject, int index, Representation representation) |
| 918 : HandlerStub() { | 935 : HandlerStub() { |
| 919 Initialize(Code::LOAD_IC, inobject, index, representation); | 936 Initialize(Code::LOAD_IC, inobject, index, representation); |
| 920 } | 937 } |
| 921 | 938 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 | IndexBits::encode(index) | 981 | IndexBits::encode(index) |
| 965 | UnboxedDoubleBits::encode(unboxed_double); | 982 | UnboxedDoubleBits::encode(unboxed_double); |
| 966 } | 983 } |
| 967 | 984 |
| 968 private: | 985 private: |
| 969 STATIC_ASSERT(KindBits::kSize == 4); | 986 STATIC_ASSERT(KindBits::kSize == 4); |
| 970 class InobjectBits: public BitField<bool, 4, 1> {}; | 987 class InobjectBits: public BitField<bool, 4, 1> {}; |
| 971 class IndexBits: public BitField<int, 5, 11> {}; | 988 class IndexBits: public BitField<int, 5, 11> {}; |
| 972 class UnboxedDoubleBits: public BitField<bool, 16, 1> {}; | 989 class UnboxedDoubleBits: public BitField<bool, 16, 1> {}; |
| 973 virtual CodeStub::Major MajorKey() { return LoadField; } | 990 virtual CodeStub::Major MajorKey() { return LoadField; } |
| 974 virtual int NotMissMinorKey() { return bit_field_; } | |
| 975 | |
| 976 int bit_field_; | |
| 977 }; | 991 }; |
| 978 | 992 |
| 979 | 993 |
| 980 class KeyedLoadFieldStub: public LoadFieldStub { | 994 class KeyedLoadFieldStub: public LoadFieldStub { |
| 981 public: | 995 public: |
| 982 KeyedLoadFieldStub(bool inobject, int index, Representation representation) | 996 KeyedLoadFieldStub(bool inobject, int index, Representation representation) |
| 983 : LoadFieldStub() { | 997 : LoadFieldStub() { |
| 984 Initialize(Code::KEYED_LOAD_IC, inobject, index, representation); | 998 Initialize(Code::KEYED_LOAD_IC, inobject, index, representation); |
| 985 } | 999 } |
| 986 | 1000 |
| 987 virtual void InitializeInterfaceDescriptor( | 1001 virtual void InitializeInterfaceDescriptor( |
| 988 Isolate* isolate, | 1002 Isolate* isolate, |
| 989 CodeStubInterfaceDescriptor* descriptor); | 1003 CodeStubInterfaceDescriptor* descriptor); |
| 990 | 1004 |
| 991 virtual Handle<Code> GenerateCode(Isolate* isolate); | 1005 virtual Handle<Code> GenerateCode(Isolate* isolate); |
| 992 | 1006 |
| 993 private: | 1007 private: |
| 994 virtual CodeStub::Major MajorKey() { return KeyedLoadField; } | 1008 virtual CodeStub::Major MajorKey() { return KeyedLoadField; } |
| 995 }; | 1009 }; |
| 996 | 1010 |
| 997 | 1011 |
| 1012 class KeyedArrayCallStub: public HICStub { |
| 1013 public: |
| 1014 KeyedArrayCallStub(bool holey, int argc) : HICStub(), argc_(argc) { |
| 1015 bit_field_ = KindBits::encode(Code::KEYED_CALL_IC) |
| 1016 | HoleyBits::encode(holey); |
| 1017 } |
| 1018 |
| 1019 virtual Code::Kind kind() const { |
| 1020 return KindBits::decode(bit_field_); |
| 1021 } |
| 1022 |
| 1023 virtual Code::ExtraICState GetExtraICState() { return bit_field_; } |
| 1024 |
| 1025 ElementsKind elements_kind() { |
| 1026 return HoleyBits::decode(bit_field_) ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; |
| 1027 } |
| 1028 |
| 1029 int argc() { return argc_; } |
| 1030 virtual int GetStubFlags() { return argc(); } |
| 1031 |
| 1032 static bool IsHoley(Handle<Code> code) { |
| 1033 Code::ExtraICState state = code->extra_ic_state(); |
| 1034 return HoleyBits::decode(state); |
| 1035 } |
| 1036 |
| 1037 virtual void InitializeInterfaceDescriptor( |
| 1038 Isolate* isolate, |
| 1039 CodeStubInterfaceDescriptor* descriptor); |
| 1040 |
| 1041 virtual Handle<Code> GenerateCode(Isolate* isolate); |
| 1042 |
| 1043 private: |
| 1044 virtual int NotMissMinorKey() { |
| 1045 return GetExtraICState() | ArgcBits::encode(argc_); |
| 1046 } |
| 1047 |
| 1048 STATIC_ASSERT(KindBits::kSize == 4); |
| 1049 class HoleyBits: public BitField<bool, 4, 1> {}; |
| 1050 STATIC_ASSERT(Code::kArgumentsBits <= kStubMinorKeyBits - 5); |
| 1051 class ArgcBits: public BitField<int, 5, Code::kArgumentsBits> {}; |
| 1052 virtual CodeStub::Major MajorKey() { return KeyedArrayCall; } |
| 1053 int bit_field_; |
| 1054 int argc_; |
| 1055 }; |
| 1056 |
| 1057 |
| 998 class BinaryOpStub: public PlatformCodeStub { | 1058 class BinaryOpStub: public PlatformCodeStub { |
| 999 public: | 1059 public: |
| 1000 BinaryOpStub(Token::Value op, OverwriteMode mode) | 1060 BinaryOpStub(Token::Value op, OverwriteMode mode) |
| 1001 : op_(op), | 1061 : op_(op), |
| 1002 mode_(mode), | 1062 mode_(mode), |
| 1003 platform_specific_bit_(false), | 1063 platform_specific_bit_(false), |
| 1004 left_type_(BinaryOpIC::UNINITIALIZED), | 1064 left_type_(BinaryOpIC::UNINITIALIZED), |
| 1005 right_type_(BinaryOpIC::UNINITIALIZED), | 1065 right_type_(BinaryOpIC::UNINITIALIZED), |
| 1006 result_type_(BinaryOpIC::UNINITIALIZED), | 1066 result_type_(BinaryOpIC::UNINITIALIZED), |
| 1007 encoded_right_arg_(false, encode_arg_value(1)) { | 1067 encoded_right_arg_(false, encode_arg_value(1)) { |
| (...skipping 1285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2293 | 2353 |
| 2294 void Generate(MacroAssembler* masm); | 2354 void Generate(MacroAssembler* masm); |
| 2295 | 2355 |
| 2296 bool fp_registers_; | 2356 bool fp_registers_; |
| 2297 StubFunctionMode function_mode_; | 2357 StubFunctionMode function_mode_; |
| 2298 | 2358 |
| 2299 DISALLOW_COPY_AND_ASSIGN(StubFailureTrampolineStub); | 2359 DISALLOW_COPY_AND_ASSIGN(StubFailureTrampolineStub); |
| 2300 }; | 2360 }; |
| 2301 | 2361 |
| 2302 | 2362 |
| 2363 class StubFailureTailCallTrampolineStub : public PlatformCodeStub { |
| 2364 public: |
| 2365 StubFailureTailCallTrampolineStub() : fp_registers_(CanUseFPRegisters()) {} |
| 2366 |
| 2367 virtual bool IsPregenerated(Isolate* isolate) V8_OVERRIDE { return true; } |
| 2368 |
| 2369 static void GenerateAheadOfTime(Isolate* isolate); |
| 2370 |
| 2371 private: |
| 2372 class FPRegisters: public BitField<bool, 0, 1> {}; |
| 2373 Major MajorKey() { return StubFailureTailCallTrampoline; } |
| 2374 int MinorKey() { return FPRegisters::encode(fp_registers_); } |
| 2375 |
| 2376 void Generate(MacroAssembler* masm); |
| 2377 |
| 2378 bool fp_registers_; |
| 2379 |
| 2380 DISALLOW_COPY_AND_ASSIGN(StubFailureTailCallTrampolineStub); |
| 2381 }; |
| 2382 |
| 2383 |
| 2303 class ProfileEntryHookStub : public PlatformCodeStub { | 2384 class ProfileEntryHookStub : public PlatformCodeStub { |
| 2304 public: | 2385 public: |
| 2305 explicit ProfileEntryHookStub() {} | 2386 explicit ProfileEntryHookStub() {} |
| 2306 | 2387 |
| 2307 // The profile entry hook function is not allowed to cause a GC. | 2388 // The profile entry hook function is not allowed to cause a GC. |
| 2308 virtual bool SometimesSetsUpAFrame() { return false; } | 2389 virtual bool SometimesSetsUpAFrame() { return false; } |
| 2309 | 2390 |
| 2310 // Generates a call to the entry hook if it's enabled. | 2391 // Generates a call to the entry hook if it's enabled. |
| 2311 static void MaybeCallEntryHook(MacroAssembler* masm); | 2392 static void MaybeCallEntryHook(MacroAssembler* masm); |
| 2312 | 2393 |
| 2313 private: | 2394 private: |
| 2314 static void EntryHookTrampoline(intptr_t function, | 2395 static void EntryHookTrampoline(intptr_t function, |
| 2315 intptr_t stack_pointer, | 2396 intptr_t stack_pointer, |
| 2316 Isolate* isolate); | 2397 Isolate* isolate); |
| 2317 | 2398 |
| 2318 Major MajorKey() { return ProfileEntryHook; } | 2399 Major MajorKey() { return ProfileEntryHook; } |
| 2319 int MinorKey() { return 0; } | 2400 int MinorKey() { return 0; } |
| 2320 | 2401 |
| 2321 void Generate(MacroAssembler* masm); | 2402 void Generate(MacroAssembler* masm); |
| 2322 | 2403 |
| 2323 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); | 2404 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); |
| 2324 }; | 2405 }; |
| 2325 | 2406 |
| 2326 } } // namespace v8::internal | 2407 } } // namespace v8::internal |
| 2327 | 2408 |
| 2328 #endif // V8_CODE_STUBS_H_ | 2409 #endif // V8_CODE_STUBS_H_ |
| OLD | NEW |