| 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 12 matching lines...) Expand all Loading... |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_CODE_STUBS_H_ | 28 #ifndef V8_CODE_STUBS_H_ |
| 29 #define V8_CODE_STUBS_H_ | 29 #define V8_CODE_STUBS_H_ |
| 30 | 30 |
| 31 #include "allocation.h" | 31 #include "allocation.h" |
| 32 #include "assembler.h" | 32 #include "assembler.h" |
| 33 #include "codegen.h" |
| 33 #include "globals.h" | 34 #include "globals.h" |
| 34 #include "codegen.h" | 35 #include "macro-assembler.h" |
| 35 | 36 |
| 36 namespace v8 { | 37 namespace v8 { |
| 37 namespace internal { | 38 namespace internal { |
| 38 | 39 |
| 39 // List of code stubs used on all platforms. | 40 // List of code stubs used on all platforms. |
| 40 #define CODE_STUB_LIST_ALL_PLATFORMS(V) \ | 41 #define CODE_STUB_LIST_ALL_PLATFORMS(V) \ |
| 41 V(CallFunction) \ | 42 V(CallFunction) \ |
| 42 V(CallConstruct) \ | 43 V(CallConstruct) \ |
| 43 V(BinaryOp) \ | 44 V(BinaryOp) \ |
| 44 V(StringAdd) \ | 45 V(StringAdd) \ |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 | 209 |
| 209 // Returns a name for logging/debugging purposes. | 210 // Returns a name for logging/debugging purposes. |
| 210 SmartArrayPointer<const char> GetName(); | 211 SmartArrayPointer<const char> GetName(); |
| 211 | 212 |
| 212 protected: | 213 protected: |
| 213 static bool CanUseFPRegisters(); | 214 static bool CanUseFPRegisters(); |
| 214 | 215 |
| 215 // Generates the assembler code for the stub. | 216 // Generates the assembler code for the stub. |
| 216 virtual Handle<Code> GenerateCode(Isolate* isolate) = 0; | 217 virtual Handle<Code> GenerateCode(Isolate* isolate) = 0; |
| 217 | 218 |
| 219 virtual void VerifyPlatformFeatures(Isolate* isolate); |
| 218 | 220 |
| 219 // Returns whether the code generated for this stub needs to be allocated as | 221 // Returns whether the code generated for this stub needs to be allocated as |
| 220 // a fixed (non-moveable) code object. | 222 // a fixed (non-moveable) code object. |
| 221 virtual bool NeedsImmovableCode() { return false; } | 223 virtual bool NeedsImmovableCode() { return false; } |
| 222 | 224 |
| 223 virtual void PrintBaseName(StringStream* stream); | 225 virtual void PrintBaseName(StringStream* stream); |
| 224 virtual void PrintState(StringStream* stream) { } | 226 virtual void PrintState(StringStream* stream) { } |
| 225 | 227 |
| 226 private: | 228 private: |
| 227 // Perform bookkeeping required after code generation when stub code is | 229 // Perform bookkeeping required after code generation when stub code is |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 virtual void Generate(MacroAssembler* masm) = 0; | 280 virtual void Generate(MacroAssembler* masm) = 0; |
| 279 }; | 281 }; |
| 280 | 282 |
| 281 | 283 |
| 282 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; | 284 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; |
| 283 | 285 |
| 284 | 286 |
| 285 struct CodeStubInterfaceDescriptor { | 287 struct CodeStubInterfaceDescriptor { |
| 286 CodeStubInterfaceDescriptor(); | 288 CodeStubInterfaceDescriptor(); |
| 287 int register_param_count_; | 289 int register_param_count_; |
| 288 const Register* stack_parameter_count_; | 290 Register stack_parameter_count_; |
| 289 // if hint_stack_parameter_count_ > 0, the code stub can optimize the | 291 // if hint_stack_parameter_count_ > 0, the code stub can optimize the |
| 290 // return sequence. Default value is -1, which means it is ignored. | 292 // return sequence. Default value is -1, which means it is ignored. |
| 291 int hint_stack_parameter_count_; | 293 int hint_stack_parameter_count_; |
| 292 StubFunctionMode function_mode_; | 294 StubFunctionMode function_mode_; |
| 293 Register* register_params_; | 295 Register* register_params_; |
| 294 Address deoptimization_handler_; | 296 Address deoptimization_handler_; |
| 295 | 297 |
| 296 int environment_length() const { | 298 int environment_length() const { |
| 297 if (stack_parameter_count_ != NULL) { | 299 if (stack_parameter_count_.is_valid()) { |
| 298 return register_param_count_ + 1; | 300 return register_param_count_ + 1; |
| 299 } | 301 } |
| 300 return register_param_count_; | 302 return register_param_count_; |
| 301 } | 303 } |
| 302 | 304 |
| 303 bool initialized() const { return register_param_count_ >= 0; } | 305 bool initialized() const { return register_param_count_ >= 0; } |
| 304 | 306 |
| 305 void SetMissHandler(ExternalReference handler) { | 307 void SetMissHandler(ExternalReference handler) { |
| 306 miss_handler_ = handler; | 308 miss_handler_ = handler; |
| 307 has_miss_handler_ = true; | 309 has_miss_handler_ = true; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 318 | 320 |
| 319 private: | 321 private: |
| 320 ExternalReference miss_handler_; | 322 ExternalReference miss_handler_; |
| 321 bool has_miss_handler_; | 323 bool has_miss_handler_; |
| 322 }; | 324 }; |
| 323 | 325 |
| 324 // A helper to make up for the fact that type Register is not fully | 326 // A helper to make up for the fact that type Register is not fully |
| 325 // defined outside of the platform directories | 327 // defined outside of the platform directories |
| 326 #define DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index) \ | 328 #define DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index) \ |
| 327 ((index) == (descriptor)->register_param_count_) \ | 329 ((index) == (descriptor)->register_param_count_) \ |
| 328 ? *((descriptor)->stack_parameter_count_) \ | 330 ? (descriptor)->stack_parameter_count_ \ |
| 329 : (descriptor)->register_params_[(index)] | 331 : (descriptor)->register_params_[(index)] |
| 330 | 332 |
| 331 | 333 |
| 332 class HydrogenCodeStub : public CodeStub { | 334 class HydrogenCodeStub : public CodeStub { |
| 333 public: | 335 public: |
| 334 enum InitializationState { | 336 enum InitializationState { |
| 335 UNINITIALIZED, | 337 UNINITIALIZED, |
| 336 INITIALIZED | 338 INITIALIZED |
| 337 }; | 339 }; |
| 338 | 340 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 // TODO(bmeurer): Move to the StringAddStub declaration once we're | 404 // TODO(bmeurer): Move to the StringAddStub declaration once we're |
| 403 // done with the translation to a hydrogen code stub. | 405 // done with the translation to a hydrogen code stub. |
| 404 enum StringAddFlags { | 406 enum StringAddFlags { |
| 405 // Omit both parameter checks. | 407 // Omit both parameter checks. |
| 406 STRING_ADD_CHECK_NONE = 0, | 408 STRING_ADD_CHECK_NONE = 0, |
| 407 // Check left parameter. | 409 // Check left parameter. |
| 408 STRING_ADD_CHECK_LEFT = 1 << 0, | 410 STRING_ADD_CHECK_LEFT = 1 << 0, |
| 409 // Check right parameter. | 411 // Check right parameter. |
| 410 STRING_ADD_CHECK_RIGHT = 1 << 1, | 412 STRING_ADD_CHECK_RIGHT = 1 << 1, |
| 411 // Check both parameters. | 413 // Check both parameters. |
| 412 STRING_ADD_CHECK_BOTH = STRING_ADD_CHECK_LEFT | STRING_ADD_CHECK_RIGHT, | 414 STRING_ADD_CHECK_BOTH = STRING_ADD_CHECK_LEFT | STRING_ADD_CHECK_RIGHT |
| 413 // Stub needs a frame before calling the runtime | |
| 414 STRING_ADD_ERECT_FRAME = 1 << 2 | |
| 415 }; | 415 }; |
| 416 | 416 |
| 417 } } // namespace v8::internal | 417 } } // namespace v8::internal |
| 418 | 418 |
| 419 #if V8_TARGET_ARCH_IA32 | 419 #if V8_TARGET_ARCH_IA32 |
| 420 #include "ia32/code-stubs-ia32.h" | 420 #include "ia32/code-stubs-ia32.h" |
| 421 #elif V8_TARGET_ARCH_X64 | 421 #elif V8_TARGET_ARCH_X64 |
| 422 #include "x64/code-stubs-x64.h" | 422 #include "x64/code-stubs-x64.h" |
| 423 #elif V8_TARGET_ARCH_A64 | 423 #elif V8_TARGET_ARCH_A64 |
| 424 #include "a64/code-stubs-a64.h" | 424 #include "a64/code-stubs-a64.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 class NumberToStringStub V8_FINAL : public HydrogenCodeStub { | 476 class NumberToStringStub V8_FINAL : public HydrogenCodeStub { |
| 477 public: | 477 public: |
| 478 NumberToStringStub() {} | 478 NumberToStringStub() {} |
| 479 | 479 |
| 480 virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE; | 480 virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE; |
| 481 | 481 |
| 482 virtual void InitializeInterfaceDescriptor( | 482 virtual void InitializeInterfaceDescriptor( |
| 483 Isolate* isolate, | 483 Isolate* isolate, |
| 484 CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; | 484 CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; |
| 485 | 485 |
| 486 static void InstallDescriptors(Isolate* isolate); |
| 487 |
| 486 // Parameters accessed via CodeStubGraphBuilder::GetParameter() | 488 // Parameters accessed via CodeStubGraphBuilder::GetParameter() |
| 487 static const int kNumber = 0; | 489 static const int kNumber = 0; |
| 488 | 490 |
| 489 private: | 491 private: |
| 490 virtual Major MajorKey() V8_OVERRIDE { return NumberToString; } | 492 virtual Major MajorKey() V8_OVERRIDE { return NumberToString; } |
| 491 virtual int NotMissMinorKey() V8_OVERRIDE { return 0; } | 493 virtual int NotMissMinorKey() V8_OVERRIDE { return 0; } |
| 492 }; | 494 }; |
| 493 | 495 |
| 494 | 496 |
| 495 class FastNewClosureStub : public HydrogenCodeStub { | 497 class FastNewClosureStub : public HydrogenCodeStub { |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1044 | 1046 |
| 1045 virtual Code::Kind GetCodeKind() const { return Code::BINARY_OP_IC; } | 1047 virtual Code::Kind GetCodeKind() const { return Code::BINARY_OP_IC; } |
| 1046 virtual InlineCacheState GetICState() { | 1048 virtual InlineCacheState GetICState() { |
| 1047 if (Max(left_state_, right_state_) == NONE) { | 1049 if (Max(left_state_, right_state_) == NONE) { |
| 1048 return ::v8::internal::UNINITIALIZED; | 1050 return ::v8::internal::UNINITIALIZED; |
| 1049 } | 1051 } |
| 1050 if (Max(left_state_, right_state_) == GENERIC) return MEGAMORPHIC; | 1052 if (Max(left_state_, right_state_) == GENERIC) return MEGAMORPHIC; |
| 1051 return MONOMORPHIC; | 1053 return MONOMORPHIC; |
| 1052 } | 1054 } |
| 1053 | 1055 |
| 1056 virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE { |
| 1057 ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2)); |
| 1058 } |
| 1059 |
| 1054 virtual Code::ExtraICState GetExtraICState() { | 1060 virtual Code::ExtraICState GetExtraICState() { |
| 1055 bool sse_field = Max(result_state_, Max(left_state_, right_state_)) > SMI && | 1061 bool sse_field = Max(result_state_, Max(left_state_, right_state_)) > SMI && |
| 1056 CpuFeatures::IsSafeForSnapshot(SSE2); | 1062 CpuFeatures::IsSafeForSnapshot(SSE2); |
| 1057 | 1063 |
| 1058 return OpBits::encode(encode_token(op_)) | 1064 return OpBits::encode(encode_token(op_)) |
| 1059 | LeftStateField::encode(left_state_) | 1065 | LeftStateField::encode(left_state_) |
| 1060 | RightStateField::encode(fixed_right_arg_.has_value | 1066 | RightStateField::encode(fixed_right_arg_.has_value |
| 1061 ? NONE : right_state_) | 1067 ? NONE : right_state_) |
| 1062 | ResultStateField::encode(result_state_) | 1068 | ResultStateField::encode(result_state_) |
| 1063 | HasFixedRightArgBits::encode(fixed_right_arg_.has_value) | 1069 | HasFixedRightArgBits::encode(fixed_right_arg_.has_value) |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1349 | 1355 |
| 1350 void Generate(MacroAssembler* masm); | 1356 void Generate(MacroAssembler* masm); |
| 1351 | 1357 |
| 1352 // The version of this stub that doesn't save doubles is generated ahead of | 1358 // The version of this stub that doesn't save doubles is generated ahead of |
| 1353 // time, so it's OK to call it from other stubs that can't cope with GC during | 1359 // time, so it's OK to call it from other stubs that can't cope with GC during |
| 1354 // their code generation. On machines that always have gp registers (x64) we | 1360 // their code generation. On machines that always have gp registers (x64) we |
| 1355 // can generate both variants ahead of time. | 1361 // can generate both variants ahead of time. |
| 1356 virtual bool IsPregenerated(Isolate* isolate) V8_OVERRIDE; | 1362 virtual bool IsPregenerated(Isolate* isolate) V8_OVERRIDE; |
| 1357 static void GenerateAheadOfTime(Isolate* isolate); | 1363 static void GenerateAheadOfTime(Isolate* isolate); |
| 1358 | 1364 |
| 1365 protected: |
| 1366 virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE { |
| 1367 ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2)); |
| 1368 }; |
| 1369 |
| 1359 private: | 1370 private: |
| 1360 void GenerateCore(MacroAssembler* masm, | 1371 void GenerateCore(MacroAssembler* masm, |
| 1361 Label* throw_normal_exception, | 1372 Label* throw_normal_exception, |
| 1362 Label* throw_termination_exception, | 1373 Label* throw_termination_exception, |
| 1363 Label* throw_out_of_memory_exception, | 1374 Label* throw_out_of_memory_exception, |
| 1364 bool do_gc, | 1375 bool do_gc, |
| 1365 bool always_allocate_scope); | 1376 bool always_allocate_scope); |
| 1366 | 1377 |
| 1367 // Number of pointers/values returned. | 1378 // Number of pointers/values returned. |
| 1368 Isolate* isolate_; | 1379 Isolate* isolate_; |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1791 } | 1802 } |
| 1792 | 1803 |
| 1793 int offset() { | 1804 int offset() { |
| 1794 return OffsetBits::decode(bit_field_); | 1805 return OffsetBits::decode(bit_field_); |
| 1795 } | 1806 } |
| 1796 | 1807 |
| 1797 void Generate(MacroAssembler* masm); | 1808 void Generate(MacroAssembler* masm); |
| 1798 | 1809 |
| 1799 virtual bool SometimesSetsUpAFrame() { return false; } | 1810 virtual bool SometimesSetsUpAFrame() { return false; } |
| 1800 | 1811 |
| 1812 protected: |
| 1813 virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE { |
| 1814 ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2)); |
| 1815 } |
| 1816 |
| 1801 private: | 1817 private: |
| 1802 static const int kBitsPerRegisterNumber = 6; | 1818 static const int kBitsPerRegisterNumber = 6; |
| 1803 STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters); | 1819 STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters); |
| 1804 class SourceRegisterBits: | 1820 class SourceRegisterBits: |
| 1805 public BitField<int, 0, kBitsPerRegisterNumber> {}; // NOLINT | 1821 public BitField<int, 0, kBitsPerRegisterNumber> {}; // NOLINT |
| 1806 class DestinationRegisterBits: | 1822 class DestinationRegisterBits: |
| 1807 public BitField<int, kBitsPerRegisterNumber, | 1823 public BitField<int, kBitsPerRegisterNumber, |
| 1808 kBitsPerRegisterNumber> {}; // NOLINT | 1824 kBitsPerRegisterNumber> {}; // NOLINT |
| 1809 class IsTruncatingBits: | 1825 class IsTruncatingBits: |
| 1810 public BitField<bool, 2 * kBitsPerRegisterNumber, 1> {}; // NOLINT | 1826 public BitField<bool, 2 * kBitsPerRegisterNumber, 1> {}; // NOLINT |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2373 int MinorKey() { return 0; } | 2389 int MinorKey() { return 0; } |
| 2374 | 2390 |
| 2375 void Generate(MacroAssembler* masm); | 2391 void Generate(MacroAssembler* masm); |
| 2376 | 2392 |
| 2377 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); | 2393 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); |
| 2378 }; | 2394 }; |
| 2379 | 2395 |
| 2380 } } // namespace v8::internal | 2396 } } // namespace v8::internal |
| 2381 | 2397 |
| 2382 #endif // V8_CODE_STUBS_H_ | 2398 #endif // V8_CODE_STUBS_H_ |
| OLD | NEW |