| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 6 | 6 |
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 DCHECK(!AreAliased(r8, r9, LoadWithVectorDescriptor::VectorRegister(), | 353 DCHECK(!AreAliased(r8, r9, LoadWithVectorDescriptor::VectorRegister(), |
| 354 LoadDescriptor::SlotRegister())); | 354 LoadDescriptor::SlotRegister())); |
| 355 | 355 |
| 356 NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8, | 356 NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8, |
| 357 r9, &miss); | 357 r9, &miss); |
| 358 __ bind(&miss); | 358 __ bind(&miss); |
| 359 PropertyAccessCompiler::TailCallBuiltin( | 359 PropertyAccessCompiler::TailCallBuiltin( |
| 360 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); | 360 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); |
| 361 } | 361 } |
| 362 | 362 |
| 363 | |
| 364 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { | |
| 365 // Return address is on the stack. | |
| 366 Label miss; | |
| 367 | |
| 368 Register receiver = LoadDescriptor::ReceiverRegister(); | |
| 369 Register index = LoadDescriptor::NameRegister(); | |
| 370 Register scratch = rdi; | |
| 371 Register result = rax; | |
| 372 DCHECK(!scratch.is(receiver) && !scratch.is(index)); | |
| 373 DCHECK(!scratch.is(LoadWithVectorDescriptor::VectorRegister()) && | |
| 374 result.is(LoadDescriptor::SlotRegister())); | |
| 375 | |
| 376 // StringCharAtGenerator doesn't use the result register until it's passed | |
| 377 // the different miss possibilities. If it did, we would have a conflict | |
| 378 // when FLAG_vector_ics is true. | |
| 379 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, | |
| 380 &miss, // When not a string. | |
| 381 &miss, // When not a number. | |
| 382 &miss, // When index out of range. | |
| 383 RECEIVER_IS_STRING); | |
| 384 char_at_generator.GenerateFast(masm); | |
| 385 __ ret(0); | |
| 386 | |
| 387 StubRuntimeCallHelper call_helper; | |
| 388 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); | |
| 389 | |
| 390 __ bind(&miss); | |
| 391 PropertyAccessCompiler::TailCallBuiltin( | |
| 392 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | |
| 393 } | |
| 394 | |
| 395 | |
| 396 void RegExpExecStub::Generate(MacroAssembler* masm) { | 363 void RegExpExecStub::Generate(MacroAssembler* masm) { |
| 397 // Just jump directly to runtime if native RegExp is not selected at compile | 364 // Just jump directly to runtime if native RegExp is not selected at compile |
| 398 // time or if regexp entry in generated code is turned off runtime switch or | 365 // time or if regexp entry in generated code is turned off runtime switch or |
| 399 // at compilation. | 366 // at compilation. |
| 400 #ifdef V8_INTERPRETED_REGEXP | 367 #ifdef V8_INTERPRETED_REGEXP |
| 401 __ TailCallRuntime(Runtime::kRegExpExec); | 368 __ TailCallRuntime(Runtime::kRegExpExec); |
| 402 #else // V8_INTERPRETED_REGEXP | 369 #else // V8_INTERPRETED_REGEXP |
| 403 | 370 |
| 404 // Stack frame on entry. | 371 // Stack frame on entry. |
| 405 // rsp[0] : return address | 372 // rsp[0] : return address |
| (...skipping 1328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1734 __ CallRuntime(Runtime::kStringCharCodeAtRT); | 1701 __ CallRuntime(Runtime::kStringCharCodeAtRT); |
| 1735 if (!result_.is(rax)) { | 1702 if (!result_.is(rax)) { |
| 1736 __ movp(result_, rax); | 1703 __ movp(result_, rax); |
| 1737 } | 1704 } |
| 1738 call_helper.AfterCall(masm); | 1705 call_helper.AfterCall(masm); |
| 1739 __ jmp(&exit_); | 1706 __ jmp(&exit_); |
| 1740 | 1707 |
| 1741 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); | 1708 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); |
| 1742 } | 1709 } |
| 1743 | 1710 |
| 1744 | |
| 1745 // ------------------------------------------------------------------------- | |
| 1746 // StringCharFromCodeGenerator | |
| 1747 | |
| 1748 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) { | |
| 1749 // Fast case of Heap::LookupSingleCharacterStringFromCode. | |
| 1750 __ JumpIfNotSmi(code_, &slow_case_); | |
| 1751 __ SmiCompare(code_, Smi::FromInt(String::kMaxOneByteCharCode)); | |
| 1752 __ j(above, &slow_case_); | |
| 1753 | |
| 1754 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex); | |
| 1755 SmiIndex index = masm->SmiToIndex(kScratchRegister, code_, kPointerSizeLog2); | |
| 1756 __ movp(result_, FieldOperand(result_, index.reg, index.scale, | |
| 1757 FixedArray::kHeaderSize)); | |
| 1758 __ CompareRoot(result_, Heap::kUndefinedValueRootIndex); | |
| 1759 __ j(equal, &slow_case_); | |
| 1760 __ bind(&exit_); | |
| 1761 } | |
| 1762 | |
| 1763 | |
| 1764 void StringCharFromCodeGenerator::GenerateSlow( | |
| 1765 MacroAssembler* masm, | |
| 1766 const RuntimeCallHelper& call_helper) { | |
| 1767 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase); | |
| 1768 | |
| 1769 __ bind(&slow_case_); | |
| 1770 call_helper.BeforeCall(masm); | |
| 1771 __ Push(code_); | |
| 1772 __ CallRuntime(Runtime::kStringCharFromCode); | |
| 1773 if (!result_.is(rax)) { | |
| 1774 __ movp(result_, rax); | |
| 1775 } | |
| 1776 call_helper.AfterCall(masm); | |
| 1777 __ jmp(&exit_); | |
| 1778 | |
| 1779 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); | |
| 1780 } | |
| 1781 | |
| 1782 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm, | 1711 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm, |
| 1783 Register left, | 1712 Register left, |
| 1784 Register right, | 1713 Register right, |
| 1785 Register scratch1, | 1714 Register scratch1, |
| 1786 Register scratch2) { | 1715 Register scratch2) { |
| 1787 Register length = scratch1; | 1716 Register length = scratch1; |
| 1788 | 1717 |
| 1789 // Compare lengths. | 1718 // Compare lengths. |
| 1790 Label check_zero_length; | 1719 Label check_zero_length; |
| 1791 __ movp(length, FieldOperand(left, String::kLengthOffset)); | 1720 __ movp(length, FieldOperand(left, String::kLengthOffset)); |
| (...skipping 1612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3404 kStackUnwindSpace, nullptr, return_value_operand, | 3333 kStackUnwindSpace, nullptr, return_value_operand, |
| 3405 NULL); | 3334 NULL); |
| 3406 } | 3335 } |
| 3407 | 3336 |
| 3408 #undef __ | 3337 #undef __ |
| 3409 | 3338 |
| 3410 } // namespace internal | 3339 } // namespace internal |
| 3411 } // namespace v8 | 3340 } // namespace v8 |
| 3412 | 3341 |
| 3413 #endif // V8_TARGET_ARCH_X64 | 3342 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |