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 |