| 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 18 matching lines...) Expand all Loading... |
| 29 #define V8_ARM_CODE_STUBS_ARM_H_ | 29 #define V8_ARM_CODE_STUBS_ARM_H_ |
| 30 | 30 |
| 31 #include "ic-inl.h" | 31 #include "ic-inl.h" |
| 32 | 32 |
| 33 namespace v8 { | 33 namespace v8 { |
| 34 namespace internal { | 34 namespace internal { |
| 35 | 35 |
| 36 | 36 |
| 37 // Compute a transcendental math function natively, or call the | 37 // Compute a transcendental math function natively, or call the |
| 38 // TranscendentalCache runtime function. | 38 // TranscendentalCache runtime function. |
| 39 class TranscendentalCacheStub: public CodeStub { | 39 class TranscendentalCacheStub: public PlatformCodeStub { |
| 40 public: | 40 public: |
| 41 enum ArgumentType { | 41 enum ArgumentType { |
| 42 TAGGED = 0 << TranscendentalCache::kTranscendentalTypeBits, | 42 TAGGED = 0 << TranscendentalCache::kTranscendentalTypeBits, |
| 43 UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits | 43 UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits |
| 44 }; | 44 }; |
| 45 | 45 |
| 46 TranscendentalCacheStub(TranscendentalCache::Type type, | 46 TranscendentalCacheStub(TranscendentalCache::Type type, |
| 47 ArgumentType argument_type) | 47 ArgumentType argument_type) |
| 48 : type_(type), argument_type_(argument_type) { } | 48 : type_(type), argument_type_(argument_type) { } |
| 49 void Generate(MacroAssembler* masm); | 49 void Generate(MacroAssembler* masm); |
| 50 private: | 50 private: |
| 51 TranscendentalCache::Type type_; | 51 TranscendentalCache::Type type_; |
| 52 ArgumentType argument_type_; | 52 ArgumentType argument_type_; |
| 53 void GenerateCallCFunction(MacroAssembler* masm, Register scratch); | 53 void GenerateCallCFunction(MacroAssembler* masm, Register scratch); |
| 54 | 54 |
| 55 Major MajorKey() { return TranscendentalCache; } | 55 Major MajorKey() { return TranscendentalCache; } |
| 56 int MinorKey() { return type_ | argument_type_; } | 56 int MinorKey() { return type_ | argument_type_; } |
| 57 Runtime::FunctionId RuntimeFunction(); | 57 Runtime::FunctionId RuntimeFunction(); |
| 58 }; | 58 }; |
| 59 | 59 |
| 60 | 60 |
| 61 class StoreBufferOverflowStub: public CodeStub { | 61 class StoreBufferOverflowStub: public PlatformCodeStub { |
| 62 public: | 62 public: |
| 63 explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp) | 63 explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp) |
| 64 : save_doubles_(save_fp) { } | 64 : save_doubles_(save_fp) { } |
| 65 | 65 |
| 66 void Generate(MacroAssembler* masm); | 66 void Generate(MacroAssembler* masm); |
| 67 | 67 |
| 68 virtual bool IsPregenerated(); | 68 virtual bool IsPregenerated(); |
| 69 static void GenerateFixedRegStubsAheadOfTime(); | 69 static void GenerateFixedRegStubsAheadOfTime(); |
| 70 virtual bool SometimesSetsUpAFrame() { return false; } | 70 virtual bool SometimesSetsUpAFrame() { return false; } |
| 71 | 71 |
| 72 private: | 72 private: |
| 73 SaveFPRegsMode save_doubles_; | 73 SaveFPRegsMode save_doubles_; |
| 74 | 74 |
| 75 Major MajorKey() { return StoreBufferOverflow; } | 75 Major MajorKey() { return StoreBufferOverflow; } |
| 76 int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; } | 76 int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; } |
| 77 }; | 77 }; |
| 78 | 78 |
| 79 | 79 |
| 80 class UnaryOpStub: public CodeStub { | 80 class UnaryOpStub: public PlatformCodeStub { |
| 81 public: | 81 public: |
| 82 UnaryOpStub(Token::Value op, | 82 UnaryOpStub(Token::Value op, |
| 83 UnaryOverwriteMode mode, | 83 UnaryOverwriteMode mode, |
| 84 UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED) | 84 UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED) |
| 85 : op_(op), | 85 : op_(op), |
| 86 mode_(mode), | 86 mode_(mode), |
| 87 operand_type_(operand_type) { | 87 operand_type_(operand_type) { |
| 88 } | 88 } |
| 89 | 89 |
| 90 private: | 90 private: |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 virtual InlineCacheState GetICState() { | 135 virtual InlineCacheState GetICState() { |
| 136 return UnaryOpIC::ToState(operand_type_); | 136 return UnaryOpIC::ToState(operand_type_); |
| 137 } | 137 } |
| 138 | 138 |
| 139 virtual void FinishCode(Handle<Code> code) { | 139 virtual void FinishCode(Handle<Code> code) { |
| 140 code->set_unary_op_type(operand_type_); | 140 code->set_unary_op_type(operand_type_); |
| 141 } | 141 } |
| 142 }; | 142 }; |
| 143 | 143 |
| 144 | 144 |
| 145 class BinaryOpStub: public CodeStub { | 145 class BinaryOpStub: public PlatformCodeStub { |
| 146 public: | 146 public: |
| 147 BinaryOpStub(Token::Value op, OverwriteMode mode) | 147 BinaryOpStub(Token::Value op, OverwriteMode mode) |
| 148 : op_(op), | 148 : op_(op), |
| 149 mode_(mode), | 149 mode_(mode), |
| 150 operands_type_(BinaryOpIC::UNINITIALIZED), | 150 operands_type_(BinaryOpIC::UNINITIALIZED), |
| 151 result_type_(BinaryOpIC::UNINITIALIZED) { | 151 result_type_(BinaryOpIC::UNINITIALIZED) { |
| 152 use_vfp2_ = CpuFeatures::IsSupported(VFP2); | 152 use_vfp2_ = CpuFeatures::IsSupported(VFP2); |
| 153 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); | 153 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); |
| 154 } | 154 } |
| 155 | 155 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 // Omit left string check in stub (left is definitely a string). | 314 // Omit left string check in stub (left is definitely a string). |
| 315 NO_STRING_CHECK_LEFT_IN_STUB = 1 << 0, | 315 NO_STRING_CHECK_LEFT_IN_STUB = 1 << 0, |
| 316 // Omit right string check in stub (right is definitely a string). | 316 // Omit right string check in stub (right is definitely a string). |
| 317 NO_STRING_CHECK_RIGHT_IN_STUB = 1 << 1, | 317 NO_STRING_CHECK_RIGHT_IN_STUB = 1 << 1, |
| 318 // Omit both string checks in stub. | 318 // Omit both string checks in stub. |
| 319 NO_STRING_CHECK_IN_STUB = | 319 NO_STRING_CHECK_IN_STUB = |
| 320 NO_STRING_CHECK_LEFT_IN_STUB | NO_STRING_CHECK_RIGHT_IN_STUB | 320 NO_STRING_CHECK_LEFT_IN_STUB | NO_STRING_CHECK_RIGHT_IN_STUB |
| 321 }; | 321 }; |
| 322 | 322 |
| 323 | 323 |
| 324 class StringAddStub: public CodeStub { | 324 class StringAddStub: public PlatformCodeStub { |
| 325 public: | 325 public: |
| 326 explicit StringAddStub(StringAddFlags flags) : flags_(flags) {} | 326 explicit StringAddStub(StringAddFlags flags) : flags_(flags) {} |
| 327 | 327 |
| 328 private: | 328 private: |
| 329 Major MajorKey() { return StringAdd; } | 329 Major MajorKey() { return StringAdd; } |
| 330 int MinorKey() { return flags_; } | 330 int MinorKey() { return flags_; } |
| 331 | 331 |
| 332 void Generate(MacroAssembler* masm); | 332 void Generate(MacroAssembler* masm); |
| 333 | 333 |
| 334 void GenerateConvertArgument(MacroAssembler* masm, | 334 void GenerateConvertArgument(MacroAssembler* masm, |
| 335 int stack_offset, | 335 int stack_offset, |
| 336 Register arg, | 336 Register arg, |
| 337 Register scratch1, | 337 Register scratch1, |
| 338 Register scratch2, | 338 Register scratch2, |
| 339 Register scratch3, | 339 Register scratch3, |
| 340 Register scratch4, | 340 Register scratch4, |
| 341 Label* slow); | 341 Label* slow); |
| 342 | 342 |
| 343 const StringAddFlags flags_; | 343 const StringAddFlags flags_; |
| 344 }; | 344 }; |
| 345 | 345 |
| 346 | 346 |
| 347 class SubStringStub: public CodeStub { | 347 class SubStringStub: public PlatformCodeStub { |
| 348 public: | 348 public: |
| 349 SubStringStub() {} | 349 SubStringStub() {} |
| 350 | 350 |
| 351 private: | 351 private: |
| 352 Major MajorKey() { return SubString; } | 352 Major MajorKey() { return SubString; } |
| 353 int MinorKey() { return 0; } | 353 int MinorKey() { return 0; } |
| 354 | 354 |
| 355 void Generate(MacroAssembler* masm); | 355 void Generate(MacroAssembler* masm); |
| 356 }; | 356 }; |
| 357 | 357 |
| 358 | 358 |
| 359 | 359 |
| 360 class StringCompareStub: public CodeStub { | 360 class StringCompareStub: public PlatformCodeStub { |
| 361 public: | 361 public: |
| 362 StringCompareStub() { } | 362 StringCompareStub() { } |
| 363 | 363 |
| 364 // Compares two flat ASCII strings and returns result in r0. | 364 // Compares two flat ASCII strings and returns result in r0. |
| 365 static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 365 static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm, |
| 366 Register left, | 366 Register left, |
| 367 Register right, | 367 Register right, |
| 368 Register scratch1, | 368 Register scratch1, |
| 369 Register scratch2, | 369 Register scratch2, |
| 370 Register scratch3, | 370 Register scratch3, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 390 Register length, | 390 Register length, |
| 391 Register scratch1, | 391 Register scratch1, |
| 392 Register scratch2, | 392 Register scratch2, |
| 393 Label* chars_not_equal); | 393 Label* chars_not_equal); |
| 394 }; | 394 }; |
| 395 | 395 |
| 396 | 396 |
| 397 // This stub can convert a signed int32 to a heap number (double). It does | 397 // This stub can convert a signed int32 to a heap number (double). It does |
| 398 // not work for int32s that are in Smi range! No GC occurs during this stub | 398 // not work for int32s that are in Smi range! No GC occurs during this stub |
| 399 // so you don't have to set up the frame. | 399 // so you don't have to set up the frame. |
| 400 class WriteInt32ToHeapNumberStub : public CodeStub { | 400 class WriteInt32ToHeapNumberStub : public PlatformCodeStub { |
| 401 public: | 401 public: |
| 402 WriteInt32ToHeapNumberStub(Register the_int, | 402 WriteInt32ToHeapNumberStub(Register the_int, |
| 403 Register the_heap_number, | 403 Register the_heap_number, |
| 404 Register scratch) | 404 Register scratch) |
| 405 : the_int_(the_int), | 405 : the_int_(the_int), |
| 406 the_heap_number_(the_heap_number), | 406 the_heap_number_(the_heap_number), |
| 407 scratch_(scratch) { } | 407 scratch_(scratch) { } |
| 408 | 408 |
| 409 bool IsPregenerated(); | 409 bool IsPregenerated(); |
| 410 static void GenerateFixedRegStubsAheadOfTime(); | 410 static void GenerateFixedRegStubsAheadOfTime(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 424 // Encode the parameters in a unique 16 bit value. | 424 // Encode the parameters in a unique 16 bit value. |
| 425 return IntRegisterBits::encode(the_int_.code()) | 425 return IntRegisterBits::encode(the_int_.code()) |
| 426 | HeapNumberRegisterBits::encode(the_heap_number_.code()) | 426 | HeapNumberRegisterBits::encode(the_heap_number_.code()) |
| 427 | ScratchRegisterBits::encode(scratch_.code()); | 427 | ScratchRegisterBits::encode(scratch_.code()); |
| 428 } | 428 } |
| 429 | 429 |
| 430 void Generate(MacroAssembler* masm); | 430 void Generate(MacroAssembler* masm); |
| 431 }; | 431 }; |
| 432 | 432 |
| 433 | 433 |
| 434 class NumberToStringStub: public CodeStub { | 434 class NumberToStringStub: public PlatformCodeStub { |
| 435 public: | 435 public: |
| 436 NumberToStringStub() { } | 436 NumberToStringStub() { } |
| 437 | 437 |
| 438 // Generate code to do a lookup in the number string cache. If the number in | 438 // Generate code to do a lookup in the number string cache. If the number in |
| 439 // the register object is found in the cache the generated code falls through | 439 // the register object is found in the cache the generated code falls through |
| 440 // with the result in the result register. The object and the result register | 440 // with the result in the result register. The object and the result register |
| 441 // can be the same. If the number is not found in the cache the code jumps to | 441 // can be the same. If the number is not found in the cache the code jumps to |
| 442 // the label not_found with only the content of register object unchanged. | 442 // the label not_found with only the content of register object unchanged. |
| 443 static void GenerateLookupNumberStringCache(MacroAssembler* masm, | 443 static void GenerateLookupNumberStringCache(MacroAssembler* masm, |
| 444 Register object, | 444 Register object, |
| 445 Register result, | 445 Register result, |
| 446 Register scratch1, | 446 Register scratch1, |
| 447 Register scratch2, | 447 Register scratch2, |
| 448 Register scratch3, | 448 Register scratch3, |
| 449 bool object_is_smi, | 449 bool object_is_smi, |
| 450 Label* not_found); | 450 Label* not_found); |
| 451 | 451 |
| 452 private: | 452 private: |
| 453 Major MajorKey() { return NumberToString; } | 453 Major MajorKey() { return NumberToString; } |
| 454 int MinorKey() { return 0; } | 454 int MinorKey() { return 0; } |
| 455 | 455 |
| 456 void Generate(MacroAssembler* masm); | 456 void Generate(MacroAssembler* masm); |
| 457 }; | 457 }; |
| 458 | 458 |
| 459 | 459 |
| 460 class RecordWriteStub: public CodeStub { | 460 class RecordWriteStub: public PlatformCodeStub { |
| 461 public: | 461 public: |
| 462 RecordWriteStub(Register object, | 462 RecordWriteStub(Register object, |
| 463 Register value, | 463 Register value, |
| 464 Register address, | 464 Register address, |
| 465 RememberedSetAction remembered_set_action, | 465 RememberedSetAction remembered_set_action, |
| 466 SaveFPRegsMode fp_mode) | 466 SaveFPRegsMode fp_mode) |
| 467 : object_(object), | 467 : object_(object), |
| 468 value_(value), | 468 value_(value), |
| 469 address_(address), | 469 address_(address), |
| 470 remembered_set_action_(remembered_set_action), | 470 remembered_set_action_(remembered_set_action), |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 | 606 |
| 607 private: | 607 private: |
| 608 Register object_; | 608 Register object_; |
| 609 Register address_; | 609 Register address_; |
| 610 Register scratch0_; | 610 Register scratch0_; |
| 611 Register scratch1_; | 611 Register scratch1_; |
| 612 | 612 |
| 613 Register GetRegThatIsNotOneOf(Register r1, | 613 Register GetRegThatIsNotOneOf(Register r1, |
| 614 Register r2, | 614 Register r2, |
| 615 Register r3) { | 615 Register r3) { |
| 616 for (int i = 0; i < Register::kNumAllocatableRegisters; i++) { | 616 for (int i = 0; i < Register::NumAllocatableRegisters(); i++) { |
| 617 Register candidate = Register::FromAllocationIndex(i); | 617 Register candidate = Register::FromAllocationIndex(i); |
| 618 if (candidate.is(r1)) continue; | 618 if (candidate.is(r1)) continue; |
| 619 if (candidate.is(r2)) continue; | 619 if (candidate.is(r2)) continue; |
| 620 if (candidate.is(r3)) continue; | 620 if (candidate.is(r3)) continue; |
| 621 return candidate; | 621 return candidate; |
| 622 } | 622 } |
| 623 UNREACHABLE(); | 623 UNREACHABLE(); |
| 624 return no_reg; | 624 return no_reg; |
| 625 } | 625 } |
| 626 friend class RecordWriteStub; | 626 friend class RecordWriteStub; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 RememberedSetAction remembered_set_action_; | 665 RememberedSetAction remembered_set_action_; |
| 666 SaveFPRegsMode save_fp_regs_mode_; | 666 SaveFPRegsMode save_fp_regs_mode_; |
| 667 Label slow_; | 667 Label slow_; |
| 668 RegisterAllocation regs_; | 668 RegisterAllocation regs_; |
| 669 }; | 669 }; |
| 670 | 670 |
| 671 | 671 |
| 672 // Enter C code from generated RegExp code in a way that allows | 672 // Enter C code from generated RegExp code in a way that allows |
| 673 // the C code to fix the return address in case of a GC. | 673 // the C code to fix the return address in case of a GC. |
| 674 // Currently only needed on ARM. | 674 // Currently only needed on ARM. |
| 675 class RegExpCEntryStub: public CodeStub { | 675 class RegExpCEntryStub: public PlatformCodeStub { |
| 676 public: | 676 public: |
| 677 RegExpCEntryStub() {} | 677 RegExpCEntryStub() {} |
| 678 virtual ~RegExpCEntryStub() {} | 678 virtual ~RegExpCEntryStub() {} |
| 679 void Generate(MacroAssembler* masm); | 679 void Generate(MacroAssembler* masm); |
| 680 | 680 |
| 681 private: | 681 private: |
| 682 Major MajorKey() { return RegExpCEntry; } | 682 Major MajorKey() { return RegExpCEntry; } |
| 683 int MinorKey() { return 0; } | 683 int MinorKey() { return 0; } |
| 684 | 684 |
| 685 bool NeedsImmovableCode() { return true; } | 685 bool NeedsImmovableCode() { return true; } |
| 686 }; | 686 }; |
| 687 | 687 |
| 688 | 688 |
| 689 // Trampoline stub to call into native code. To call safely into native code | 689 // Trampoline stub to call into native code. To call safely into native code |
| 690 // in the presence of compacting GC (which can move code objects) we need to | 690 // in the presence of compacting GC (which can move code objects) we need to |
| 691 // keep the code which called into native pinned in the memory. Currently the | 691 // keep the code which called into native pinned in the memory. Currently the |
| 692 // simplest approach is to generate such stub early enough so it can never be | 692 // simplest approach is to generate such stub early enough so it can never be |
| 693 // moved by GC | 693 // moved by GC |
| 694 class DirectCEntryStub: public CodeStub { | 694 class DirectCEntryStub: public PlatformCodeStub { |
| 695 public: | 695 public: |
| 696 DirectCEntryStub() {} | 696 DirectCEntryStub() {} |
| 697 void Generate(MacroAssembler* masm); | 697 void Generate(MacroAssembler* masm); |
| 698 void GenerateCall(MacroAssembler* masm, ExternalReference function); | 698 void GenerateCall(MacroAssembler* masm, ExternalReference function); |
| 699 void GenerateCall(MacroAssembler* masm, Register target); | 699 void GenerateCall(MacroAssembler* masm, Register target); |
| 700 | 700 |
| 701 private: | 701 private: |
| 702 Major MajorKey() { return DirectCEntry; } | 702 Major MajorKey() { return DirectCEntry; } |
| 703 int MinorKey() { return 0; } | 703 int MinorKey() { return 0; } |
| 704 | 704 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 DwVfpRegister dst, | 843 DwVfpRegister dst, |
| 844 Register dst1, | 844 Register dst1, |
| 845 Register dst2, | 845 Register dst2, |
| 846 Register heap_number_map, | 846 Register heap_number_map, |
| 847 Register scratch1, | 847 Register scratch1, |
| 848 Register scratch2, | 848 Register scratch2, |
| 849 Label* not_number); | 849 Label* not_number); |
| 850 }; | 850 }; |
| 851 | 851 |
| 852 | 852 |
| 853 class StringDictionaryLookupStub: public CodeStub { | 853 class StringDictionaryLookupStub: public PlatformCodeStub { |
| 854 public: | 854 public: |
| 855 enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; | 855 enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; |
| 856 | 856 |
| 857 explicit StringDictionaryLookupStub(LookupMode mode) : mode_(mode) { } | 857 explicit StringDictionaryLookupStub(LookupMode mode) : mode_(mode) { } |
| 858 | 858 |
| 859 void Generate(MacroAssembler* masm); | 859 void Generate(MacroAssembler* masm); |
| 860 | 860 |
| 861 static void GenerateNegativeLookup(MacroAssembler* masm, | 861 static void GenerateNegativeLookup(MacroAssembler* masm, |
| 862 Label* miss, | 862 Label* miss, |
| 863 Label* done, | 863 Label* done, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 896 | 896 |
| 897 class LookupModeBits: public BitField<LookupMode, 0, 1> {}; | 897 class LookupModeBits: public BitField<LookupMode, 0, 1> {}; |
| 898 | 898 |
| 899 LookupMode mode_; | 899 LookupMode mode_; |
| 900 }; | 900 }; |
| 901 | 901 |
| 902 | 902 |
| 903 } } // namespace v8::internal | 903 } } // namespace v8::internal |
| 904 | 904 |
| 905 #endif // V8_ARM_CODE_STUBS_ARM_H_ | 905 #endif // V8_ARM_CODE_STUBS_ARM_H_ |
| OLD | NEW |