OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 19 matching lines...) Expand all Loading... |
30 | 30 |
31 #include "ic-inl.h" | 31 #include "ic-inl.h" |
32 #include "type-info.h" | 32 #include "type-info.h" |
33 | 33 |
34 namespace v8 { | 34 namespace v8 { |
35 namespace internal { | 35 namespace internal { |
36 | 36 |
37 | 37 |
38 // Compute a transcendental math function natively, or call the | 38 // Compute a transcendental math function natively, or call the |
39 // TranscendentalCache runtime function. | 39 // TranscendentalCache runtime function. |
40 class TranscendentalCacheStub: public CodeStub { | 40 class TranscendentalCacheStub: public PlatformCodeStub { |
41 public: | 41 public: |
42 enum ArgumentType { | 42 enum ArgumentType { |
43 TAGGED = 0, | 43 TAGGED = 0, |
44 UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits | 44 UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits |
45 }; | 45 }; |
46 | 46 |
47 explicit TranscendentalCacheStub(TranscendentalCache::Type type, | 47 explicit TranscendentalCacheStub(TranscendentalCache::Type type, |
48 ArgumentType argument_type) | 48 ArgumentType argument_type) |
49 : type_(type), argument_type_(argument_type) {} | 49 : type_(type), argument_type_(argument_type) {} |
50 void Generate(MacroAssembler* masm); | 50 void Generate(MacroAssembler* masm); |
51 static void GenerateOperation(MacroAssembler* masm, | 51 static void GenerateOperation(MacroAssembler* masm, |
52 TranscendentalCache::Type type); | 52 TranscendentalCache::Type type); |
53 private: | 53 private: |
54 TranscendentalCache::Type type_; | 54 TranscendentalCache::Type type_; |
55 ArgumentType argument_type_; | 55 ArgumentType argument_type_; |
56 | 56 |
57 Major MajorKey() { return TranscendentalCache; } | 57 Major MajorKey() { return TranscendentalCache; } |
58 int MinorKey() { return type_ | argument_type_; } | 58 int MinorKey() { return type_ | argument_type_; } |
59 Runtime::FunctionId RuntimeFunction(); | 59 Runtime::FunctionId RuntimeFunction(); |
60 }; | 60 }; |
61 | 61 |
62 | 62 |
63 class StoreBufferOverflowStub: public CodeStub { | 63 class StoreBufferOverflowStub: public PlatformCodeStub { |
64 public: | 64 public: |
65 explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp) | 65 explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp) |
66 : save_doubles_(save_fp) { } | 66 : save_doubles_(save_fp) { } |
67 | 67 |
68 void Generate(MacroAssembler* masm); | 68 void Generate(MacroAssembler* masm); |
69 | 69 |
70 virtual bool IsPregenerated() { return true; } | 70 virtual bool IsPregenerated() { return true; } |
71 static void GenerateFixedRegStubsAheadOfTime(); | 71 static void GenerateFixedRegStubsAheadOfTime(); |
72 virtual bool SometimesSetsUpAFrame() { return false; } | 72 virtual bool SometimesSetsUpAFrame() { return false; } |
73 | 73 |
74 private: | 74 private: |
75 SaveFPRegsMode save_doubles_; | 75 SaveFPRegsMode save_doubles_; |
76 | 76 |
77 Major MajorKey() { return StoreBufferOverflow; } | 77 Major MajorKey() { return StoreBufferOverflow; } |
78 int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; } | 78 int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; } |
79 }; | 79 }; |
80 | 80 |
81 | 81 |
82 // Flag that indicates how to generate code for the stub GenericBinaryOpStub. | 82 // Flag that indicates how to generate code for the stub GenericBinaryOpStub. |
83 enum GenericBinaryFlags { | 83 enum GenericBinaryFlags { |
84 NO_GENERIC_BINARY_FLAGS = 0, | 84 NO_GENERIC_BINARY_FLAGS = 0, |
85 NO_SMI_CODE_IN_STUB = 1 << 0 // Omit smi code in stub. | 85 NO_SMI_CODE_IN_STUB = 1 << 0 // Omit smi code in stub. |
86 }; | 86 }; |
87 | 87 |
88 | 88 |
89 class UnaryOpStub: public CodeStub { | 89 class UnaryOpStub: public PlatformCodeStub { |
90 public: | 90 public: |
91 UnaryOpStub(Token::Value op, | 91 UnaryOpStub(Token::Value op, |
92 UnaryOverwriteMode mode, | 92 UnaryOverwriteMode mode, |
93 UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED) | 93 UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED) |
94 : op_(op), | 94 : op_(op), |
95 mode_(mode), | 95 mode_(mode), |
96 operand_type_(operand_type) { | 96 operand_type_(operand_type) { |
97 } | 97 } |
98 | 98 |
99 private: | 99 private: |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 virtual InlineCacheState GetICState() { | 150 virtual InlineCacheState GetICState() { |
151 return UnaryOpIC::ToState(operand_type_); | 151 return UnaryOpIC::ToState(operand_type_); |
152 } | 152 } |
153 | 153 |
154 virtual void FinishCode(Handle<Code> code) { | 154 virtual void FinishCode(Handle<Code> code) { |
155 code->set_unary_op_type(operand_type_); | 155 code->set_unary_op_type(operand_type_); |
156 } | 156 } |
157 }; | 157 }; |
158 | 158 |
159 | 159 |
160 class BinaryOpStub: public CodeStub { | 160 class BinaryOpStub: public PlatformCodeStub { |
161 public: | 161 public: |
162 BinaryOpStub(Token::Value op, OverwriteMode mode) | 162 BinaryOpStub(Token::Value op, OverwriteMode mode) |
163 : op_(op), | 163 : op_(op), |
164 mode_(mode), | 164 mode_(mode), |
165 operands_type_(BinaryOpIC::UNINITIALIZED), | 165 operands_type_(BinaryOpIC::UNINITIALIZED), |
166 result_type_(BinaryOpIC::UNINITIALIZED) { | 166 result_type_(BinaryOpIC::UNINITIALIZED) { |
167 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); | 167 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); |
168 } | 168 } |
169 | 169 |
170 BinaryOpStub( | 170 BinaryOpStub( |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 // Omit left string check in stub (left is definitely a string). | 305 // Omit left string check in stub (left is definitely a string). |
306 NO_STRING_CHECK_LEFT_IN_STUB = 1 << 0, | 306 NO_STRING_CHECK_LEFT_IN_STUB = 1 << 0, |
307 // Omit right string check in stub (right is definitely a string). | 307 // Omit right string check in stub (right is definitely a string). |
308 NO_STRING_CHECK_RIGHT_IN_STUB = 1 << 1, | 308 NO_STRING_CHECK_RIGHT_IN_STUB = 1 << 1, |
309 // Omit both string checks in stub. | 309 // Omit both string checks in stub. |
310 NO_STRING_CHECK_IN_STUB = | 310 NO_STRING_CHECK_IN_STUB = |
311 NO_STRING_CHECK_LEFT_IN_STUB | NO_STRING_CHECK_RIGHT_IN_STUB | 311 NO_STRING_CHECK_LEFT_IN_STUB | NO_STRING_CHECK_RIGHT_IN_STUB |
312 }; | 312 }; |
313 | 313 |
314 | 314 |
315 class StringAddStub: public CodeStub { | 315 class StringAddStub: public PlatformCodeStub { |
316 public: | 316 public: |
317 explicit StringAddStub(StringAddFlags flags) : flags_(flags) {} | 317 explicit StringAddStub(StringAddFlags flags) : flags_(flags) {} |
318 | 318 |
319 private: | 319 private: |
320 Major MajorKey() { return StringAdd; } | 320 Major MajorKey() { return StringAdd; } |
321 int MinorKey() { return flags_; } | 321 int MinorKey() { return flags_; } |
322 | 322 |
323 void Generate(MacroAssembler* masm); | 323 void Generate(MacroAssembler* masm); |
324 | 324 |
325 void GenerateConvertArgument(MacroAssembler* masm, | 325 void GenerateConvertArgument(MacroAssembler* masm, |
326 int stack_offset, | 326 int stack_offset, |
327 Register arg, | 327 Register arg, |
328 Register scratch1, | 328 Register scratch1, |
329 Register scratch2, | 329 Register scratch2, |
330 Register scratch3, | 330 Register scratch3, |
331 Label* slow); | 331 Label* slow); |
332 | 332 |
333 const StringAddFlags flags_; | 333 const StringAddFlags flags_; |
334 }; | 334 }; |
335 | 335 |
336 | 336 |
337 class SubStringStub: public CodeStub { | 337 class SubStringStub: public PlatformCodeStub { |
338 public: | 338 public: |
339 SubStringStub() {} | 339 SubStringStub() {} |
340 | 340 |
341 private: | 341 private: |
342 Major MajorKey() { return SubString; } | 342 Major MajorKey() { return SubString; } |
343 int MinorKey() { return 0; } | 343 int MinorKey() { return 0; } |
344 | 344 |
345 void Generate(MacroAssembler* masm); | 345 void Generate(MacroAssembler* masm); |
346 }; | 346 }; |
347 | 347 |
348 | 348 |
349 class StringCompareStub: public CodeStub { | 349 class StringCompareStub: public PlatformCodeStub { |
350 public: | 350 public: |
351 StringCompareStub() {} | 351 StringCompareStub() {} |
352 | 352 |
353 // Compares two flat ASCII strings and returns result in rax. | 353 // Compares two flat ASCII strings and returns result in rax. |
354 static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 354 static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm, |
355 Register left, | 355 Register left, |
356 Register right, | 356 Register right, |
357 Register scratch1, | 357 Register scratch1, |
358 Register scratch2, | 358 Register scratch2, |
359 Register scratch3, | 359 Register scratch3, |
(...skipping 16 matching lines...) Expand all Loading... |
376 MacroAssembler* masm, | 376 MacroAssembler* masm, |
377 Register left, | 377 Register left, |
378 Register right, | 378 Register right, |
379 Register length, | 379 Register length, |
380 Register scratch, | 380 Register scratch, |
381 Label* chars_not_equal, | 381 Label* chars_not_equal, |
382 Label::Distance near_jump = Label::kFar); | 382 Label::Distance near_jump = Label::kFar); |
383 }; | 383 }; |
384 | 384 |
385 | 385 |
386 class NumberToStringStub: public CodeStub { | 386 class NumberToStringStub: public PlatformCodeStub { |
387 public: | 387 public: |
388 NumberToStringStub() { } | 388 NumberToStringStub() { } |
389 | 389 |
390 // Generate code to do a lookup in the number string cache. If the number in | 390 // Generate code to do a lookup in the number string cache. If the number in |
391 // the register object is found in the cache the generated code falls through | 391 // the register object is found in the cache the generated code falls through |
392 // with the result in the result register. The object and the result register | 392 // with the result in the result register. The object and the result register |
393 // can be the same. If the number is not found in the cache the code jumps to | 393 // can be the same. If the number is not found in the cache the code jumps to |
394 // the label not_found with only the content of register object unchanged. | 394 // the label not_found with only the content of register object unchanged. |
395 static void GenerateLookupNumberStringCache(MacroAssembler* masm, | 395 static void GenerateLookupNumberStringCache(MacroAssembler* masm, |
396 Register object, | 396 Register object, |
397 Register result, | 397 Register result, |
398 Register scratch1, | 398 Register scratch1, |
399 Register scratch2, | 399 Register scratch2, |
400 bool object_is_smi, | 400 bool object_is_smi, |
401 Label* not_found); | 401 Label* not_found); |
402 | 402 |
403 private: | 403 private: |
404 static void GenerateConvertHashCodeToIndex(MacroAssembler* masm, | 404 static void GenerateConvertHashCodeToIndex(MacroAssembler* masm, |
405 Register hash, | 405 Register hash, |
406 Register mask); | 406 Register mask); |
407 | 407 |
408 Major MajorKey() { return NumberToString; } | 408 Major MajorKey() { return NumberToString; } |
409 int MinorKey() { return 0; } | 409 int MinorKey() { return 0; } |
410 | 410 |
411 void Generate(MacroAssembler* masm); | 411 void Generate(MacroAssembler* masm); |
412 }; | 412 }; |
413 | 413 |
414 | 414 |
415 class StringDictionaryLookupStub: public CodeStub { | 415 class StringDictionaryLookupStub: public PlatformCodeStub { |
416 public: | 416 public: |
417 enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; | 417 enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; |
418 | 418 |
419 StringDictionaryLookupStub(Register dictionary, | 419 StringDictionaryLookupStub(Register dictionary, |
420 Register result, | 420 Register result, |
421 Register index, | 421 Register index, |
422 LookupMode mode) | 422 LookupMode mode) |
423 : dictionary_(dictionary), result_(result), index_(index), mode_(mode) { } | 423 : dictionary_(dictionary), result_(result), index_(index), mode_(mode) { } |
424 | 424 |
425 void Generate(MacroAssembler* masm); | 425 void Generate(MacroAssembler* masm); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 class IndexBits: public BitField<int, 8, 4> {}; | 467 class IndexBits: public BitField<int, 8, 4> {}; |
468 class LookupModeBits: public BitField<LookupMode, 12, 1> {}; | 468 class LookupModeBits: public BitField<LookupMode, 12, 1> {}; |
469 | 469 |
470 Register dictionary_; | 470 Register dictionary_; |
471 Register result_; | 471 Register result_; |
472 Register index_; | 472 Register index_; |
473 LookupMode mode_; | 473 LookupMode mode_; |
474 }; | 474 }; |
475 | 475 |
476 | 476 |
477 class RecordWriteStub: public CodeStub { | 477 class RecordWriteStub: public PlatformCodeStub { |
478 public: | 478 public: |
479 RecordWriteStub(Register object, | 479 RecordWriteStub(Register object, |
480 Register value, | 480 Register value, |
481 Register address, | 481 Register address, |
482 RememberedSetAction remembered_set_action, | 482 RememberedSetAction remembered_set_action, |
483 SaveFPRegsMode fp_mode) | 483 SaveFPRegsMode fp_mode) |
484 : object_(object), | 484 : object_(object), |
485 value_(value), | 485 value_(value), |
486 address_(address), | 486 address_(address), |
487 remembered_set_action_(remembered_set_action), | 487 remembered_set_action_(remembered_set_action), |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 Register scratch0_orig_; | 650 Register scratch0_orig_; |
651 Register object_; | 651 Register object_; |
652 Register address_; | 652 Register address_; |
653 Register scratch0_; | 653 Register scratch0_; |
654 Register scratch1_; | 654 Register scratch1_; |
655 // Third scratch register is always rcx. | 655 // Third scratch register is always rcx. |
656 | 656 |
657 Register GetRegThatIsNotRcxOr(Register r1, | 657 Register GetRegThatIsNotRcxOr(Register r1, |
658 Register r2, | 658 Register r2, |
659 Register r3) { | 659 Register r3) { |
660 for (int i = 0; i < Register::kNumAllocatableRegisters; i++) { | 660 for (int i = 0; i < Register::NumAllocatableRegisters(); i++) { |
661 Register candidate = Register::FromAllocationIndex(i); | 661 Register candidate = Register::FromAllocationIndex(i); |
662 if (candidate.is(rcx)) continue; | 662 if (candidate.is(rcx)) continue; |
663 if (candidate.is(r1)) continue; | 663 if (candidate.is(r1)) continue; |
664 if (candidate.is(r2)) continue; | 664 if (candidate.is(r2)) continue; |
665 if (candidate.is(r3)) continue; | 665 if (candidate.is(r3)) continue; |
666 return candidate; | 666 return candidate; |
667 } | 667 } |
668 UNREACHABLE(); | 668 UNREACHABLE(); |
669 return no_reg; | 669 return no_reg; |
670 } | 670 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 RememberedSetAction remembered_set_action_; | 710 RememberedSetAction remembered_set_action_; |
711 SaveFPRegsMode save_fp_regs_mode_; | 711 SaveFPRegsMode save_fp_regs_mode_; |
712 Label slow_; | 712 Label slow_; |
713 RegisterAllocation regs_; | 713 RegisterAllocation regs_; |
714 }; | 714 }; |
715 | 715 |
716 | 716 |
717 } } // namespace v8::internal | 717 } } // namespace v8::internal |
718 | 718 |
719 #endif // V8_X64_CODE_STUBS_X64_H_ | 719 #endif // V8_X64_CODE_STUBS_X64_H_ |
OLD | NEW |