Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 430503007: Rename ASSERT* to DCHECK*. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE and fixes Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | src/x64/codegen-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 344
345 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { 345 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
346 // Update the static counter each time a new code stub is generated. 346 // Update the static counter each time a new code stub is generated.
347 isolate()->counters()->code_stubs()->Increment(); 347 isolate()->counters()->code_stubs()->Increment();
348 348
349 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(); 349 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
350 int param_count = descriptor->GetEnvironmentParameterCount(); 350 int param_count = descriptor->GetEnvironmentParameterCount();
351 { 351 {
352 // Call the runtime system in a fresh internal frame. 352 // Call the runtime system in a fresh internal frame.
353 FrameScope scope(masm, StackFrame::INTERNAL); 353 FrameScope scope(masm, StackFrame::INTERNAL);
354 ASSERT(param_count == 0 || 354 DCHECK(param_count == 0 ||
355 rax.is(descriptor->GetEnvironmentParameterRegister( 355 rax.is(descriptor->GetEnvironmentParameterRegister(
356 param_count - 1))); 356 param_count - 1)));
357 // Push arguments 357 // Push arguments
358 for (int i = 0; i < param_count; ++i) { 358 for (int i = 0; i < param_count; ++i) {
359 __ Push(descriptor->GetEnvironmentParameterRegister(i)); 359 __ Push(descriptor->GetEnvironmentParameterRegister(i));
360 } 360 }
361 ExternalReference miss = descriptor->miss_handler(); 361 ExternalReference miss = descriptor->miss_handler();
362 __ CallExternalReference(miss, param_count); 362 __ CallExternalReference(miss, param_count);
363 } 363 }
364 364
(...skipping 28 matching lines...) Expand all
393 // Leaves rdx and rax unchanged. SmiOperands assumes both are smis. 393 // Leaves rdx and rax unchanged. SmiOperands assumes both are smis.
394 // NumberOperands assumes both are smis or heap numbers. 394 // NumberOperands assumes both are smis or heap numbers.
395 static void LoadSSE2UnknownOperands(MacroAssembler* masm, 395 static void LoadSSE2UnknownOperands(MacroAssembler* masm,
396 Label* not_numbers); 396 Label* not_numbers);
397 }; 397 };
398 398
399 399
400 void DoubleToIStub::Generate(MacroAssembler* masm) { 400 void DoubleToIStub::Generate(MacroAssembler* masm) {
401 Register input_reg = this->source(); 401 Register input_reg = this->source();
402 Register final_result_reg = this->destination(); 402 Register final_result_reg = this->destination();
403 ASSERT(is_truncating()); 403 DCHECK(is_truncating());
404 404
405 Label check_negative, process_64_bits, done; 405 Label check_negative, process_64_bits, done;
406 406
407 int double_offset = offset(); 407 int double_offset = offset();
408 408
409 // Account for return address and saved regs if input is rsp. 409 // Account for return address and saved regs if input is rsp.
410 if (input_reg.is(rsp)) double_offset += 3 * kRegisterSize; 410 if (input_reg.is(rsp)) double_offset += 3 * kRegisterSize;
411 411
412 MemOperand mantissa_operand(MemOperand(input_reg, double_offset)); 412 MemOperand mantissa_operand(MemOperand(input_reg, double_offset));
413 MemOperand exponent_operand(MemOperand(input_reg, 413 MemOperand exponent_operand(MemOperand(input_reg,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 __ cmpl(exponent_operand, Immediate(0)); 465 __ cmpl(exponent_operand, Immediate(0));
466 } 466 }
467 __ cmovl(greater, result_reg, scratch1); 467 __ cmovl(greater, result_reg, scratch1);
468 468
469 // Restore registers 469 // Restore registers
470 __ bind(&done); 470 __ bind(&done);
471 if (stash_exponent_copy) { 471 if (stash_exponent_copy) {
472 __ addp(rsp, Immediate(kDoubleSize)); 472 __ addp(rsp, Immediate(kDoubleSize));
473 } 473 }
474 if (!final_result_reg.is(result_reg)) { 474 if (!final_result_reg.is(result_reg)) {
475 ASSERT(final_result_reg.is(rcx)); 475 DCHECK(final_result_reg.is(rcx));
476 __ movl(final_result_reg, result_reg); 476 __ movl(final_result_reg, result_reg);
477 } 477 }
478 __ popq(save_reg); 478 __ popq(save_reg);
479 __ popq(scratch1); 479 __ popq(scratch1);
480 __ ret(0); 480 __ ret(0);
481 } 481 }
482 482
483 483
484 void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm, 484 void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm,
485 Label* not_numbers) { 485 Label* not_numbers) {
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 // as heap number in rax. 746 // as heap number in rax.
747 __ bind(&done); 747 __ bind(&done);
748 __ AllocateHeapNumber(rax, rcx, &call_runtime); 748 __ AllocateHeapNumber(rax, rcx, &call_runtime);
749 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), double_result); 749 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), double_result);
750 __ IncrementCounter(counters->math_pow(), 1); 750 __ IncrementCounter(counters->math_pow(), 1);
751 __ ret(2 * kPointerSize); 751 __ ret(2 * kPointerSize);
752 } else { 752 } else {
753 __ bind(&call_runtime); 753 __ bind(&call_runtime);
754 // Move base to the correct argument register. Exponent is already in xmm1. 754 // Move base to the correct argument register. Exponent is already in xmm1.
755 __ movsd(xmm0, double_base); 755 __ movsd(xmm0, double_base);
756 ASSERT(double_exponent.is(xmm1)); 756 DCHECK(double_exponent.is(xmm1));
757 { 757 {
758 AllowExternalCallThatCantCauseGC scope(masm); 758 AllowExternalCallThatCantCauseGC scope(masm);
759 __ PrepareCallCFunction(2); 759 __ PrepareCallCFunction(2);
760 __ CallCFunction( 760 __ CallCFunction(
761 ExternalReference::power_double_double_function(isolate()), 2); 761 ExternalReference::power_double_double_function(isolate()), 2);
762 } 762 }
763 // Return value is in xmm0. 763 // Return value is in xmm0.
764 __ movsd(double_result, xmm0); 764 __ movsd(double_result, xmm0);
765 765
766 __ bind(&done); 766 __ bind(&done);
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 // (11) Sliced string. Replace subject with parent. Go to (5a). 1625 // (11) Sliced string. Replace subject with parent. Go to (5a).
1626 // Load offset into r14 and replace subject string with parent. 1626 // Load offset into r14 and replace subject string with parent.
1627 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset)); 1627 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset));
1628 __ movp(rdi, FieldOperand(rdi, SlicedString::kParentOffset)); 1628 __ movp(rdi, FieldOperand(rdi, SlicedString::kParentOffset));
1629 __ jmp(&check_underlying); 1629 __ jmp(&check_underlying);
1630 #endif // V8_INTERPRETED_REGEXP 1630 #endif // V8_INTERPRETED_REGEXP
1631 } 1631 }
1632 1632
1633 1633
1634 static int NegativeComparisonResult(Condition cc) { 1634 static int NegativeComparisonResult(Condition cc) {
1635 ASSERT(cc != equal); 1635 DCHECK(cc != equal);
1636 ASSERT((cc == less) || (cc == less_equal) 1636 DCHECK((cc == less) || (cc == less_equal)
1637 || (cc == greater) || (cc == greater_equal)); 1637 || (cc == greater) || (cc == greater_equal));
1638 return (cc == greater || cc == greater_equal) ? LESS : GREATER; 1638 return (cc == greater || cc == greater_equal) ? LESS : GREATER;
1639 } 1639 }
1640 1640
1641 1641
1642 static void CheckInputType(MacroAssembler* masm, 1642 static void CheckInputType(MacroAssembler* masm,
1643 Register input, 1643 Register input,
1644 CompareIC::State expected, 1644 CompareIC::State expected,
1645 Label* fail) { 1645 Label* fail) {
1646 Label ok; 1646 Label ok;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1816 __ j(parity_even, &unordered, Label::kNear); 1816 __ j(parity_even, &unordered, Label::kNear);
1817 // Return a result of -1, 0, or 1, based on EFLAGS. 1817 // Return a result of -1, 0, or 1, based on EFLAGS.
1818 __ setcc(above, rax); 1818 __ setcc(above, rax);
1819 __ setcc(below, rcx); 1819 __ setcc(below, rcx);
1820 __ subp(rax, rcx); 1820 __ subp(rax, rcx);
1821 __ ret(0); 1821 __ ret(0);
1822 1822
1823 // If one of the numbers was NaN, then the result is always false. 1823 // If one of the numbers was NaN, then the result is always false.
1824 // The cc is never not-equal. 1824 // The cc is never not-equal.
1825 __ bind(&unordered); 1825 __ bind(&unordered);
1826 ASSERT(cc != not_equal); 1826 DCHECK(cc != not_equal);
1827 if (cc == less || cc == less_equal) { 1827 if (cc == less || cc == less_equal) {
1828 __ Set(rax, 1); 1828 __ Set(rax, 1);
1829 } else { 1829 } else {
1830 __ Set(rax, -1); 1830 __ Set(rax, -1);
1831 } 1831 }
1832 __ ret(0); 1832 __ ret(0);
1833 1833
1834 // The number comparison code did not provide a valid result. 1834 // The number comparison code did not provide a valid result.
1835 __ bind(&non_number_comparison); 1835 __ bind(&non_number_comparison);
1836 1836
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after
2458 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. 2458 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9.
2459 // Pass argv and argc as two parameters. The arguments object will 2459 // Pass argv and argc as two parameters. The arguments object will
2460 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION(). 2460 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION().
2461 if (result_size_ < 2) { 2461 if (result_size_ < 2) {
2462 // Pass a pointer to the Arguments object as the first argument. 2462 // Pass a pointer to the Arguments object as the first argument.
2463 // Return result in single register (rax). 2463 // Return result in single register (rax).
2464 __ movp(rcx, r14); // argc. 2464 __ movp(rcx, r14); // argc.
2465 __ movp(rdx, r15); // argv. 2465 __ movp(rdx, r15); // argv.
2466 __ Move(r8, ExternalReference::isolate_address(isolate())); 2466 __ Move(r8, ExternalReference::isolate_address(isolate()));
2467 } else { 2467 } else {
2468 ASSERT_EQ(2, result_size_); 2468 DCHECK_EQ(2, result_size_);
2469 // Pass a pointer to the result location as the first argument. 2469 // Pass a pointer to the result location as the first argument.
2470 __ leap(rcx, StackSpaceOperand(2)); 2470 __ leap(rcx, StackSpaceOperand(2));
2471 // Pass a pointer to the Arguments object as the second argument. 2471 // Pass a pointer to the Arguments object as the second argument.
2472 __ movp(rdx, r14); // argc. 2472 __ movp(rdx, r14); // argc.
2473 __ movp(r8, r15); // argv. 2473 __ movp(r8, r15); // argv.
2474 __ Move(r9, ExternalReference::isolate_address(isolate())); 2474 __ Move(r9, ExternalReference::isolate_address(isolate()));
2475 } 2475 }
2476 2476
2477 #else // _WIN64 2477 #else // _WIN64
2478 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. 2478 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
2479 __ movp(rdi, r14); // argc. 2479 __ movp(rdi, r14); // argc.
2480 __ movp(rsi, r15); // argv. 2480 __ movp(rsi, r15); // argv.
2481 __ Move(rdx, ExternalReference::isolate_address(isolate())); 2481 __ Move(rdx, ExternalReference::isolate_address(isolate()));
2482 #endif 2482 #endif
2483 __ call(rbx); 2483 __ call(rbx);
2484 // Result is in rax - do not destroy this register! 2484 // Result is in rax - do not destroy this register!
2485 2485
2486 #ifdef _WIN64 2486 #ifdef _WIN64
2487 // If return value is on the stack, pop it to registers. 2487 // If return value is on the stack, pop it to registers.
2488 if (result_size_ > 1) { 2488 if (result_size_ > 1) {
2489 ASSERT_EQ(2, result_size_); 2489 DCHECK_EQ(2, result_size_);
2490 // Read result values stored on stack. Result is stored 2490 // Read result values stored on stack. Result is stored
2491 // above the four argument mirror slots and the two 2491 // above the four argument mirror slots and the two
2492 // Arguments object slots. 2492 // Arguments object slots.
2493 __ movq(rax, Operand(rsp, 6 * kRegisterSize)); 2493 __ movq(rax, Operand(rsp, 6 * kRegisterSize));
2494 __ movq(rdx, Operand(rsp, 7 * kRegisterSize)); 2494 __ movq(rdx, Operand(rsp, 7 * kRegisterSize));
2495 } 2495 }
2496 #endif 2496 #endif
2497 2497
2498 // Runtime functions should not return 'the hole'. Allowing it to escape may 2498 // Runtime functions should not return 'the hole'. Allowing it to escape may
2499 // lead to crashes in the IC code later. 2499 // lead to crashes in the IC code later.
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
2753 kPointerSize == kInt64Size ? 0xBA49FF78 : 0xBA41FF78; 2753 kPointerSize == kInt64Size ? 0xBA49FF78 : 0xBA41FF78;
2754 // The last 4 bytes of the instruction sequence 2754 // The last 4 bytes of the instruction sequence
2755 // __ j(not_equal, &cache_miss); 2755 // __ j(not_equal, &cache_miss);
2756 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); 2756 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
2757 // before the offset of the hole value in the root array. 2757 // before the offset of the hole value in the root array.
2758 static const unsigned int kWordBeforeResultValue = 2758 static const unsigned int kWordBeforeResultValue =
2759 kPointerSize == kInt64Size ? 0x458B4906 : 0x458B4106; 2759 kPointerSize == kInt64Size ? 0x458B4906 : 0x458B4106;
2760 2760
2761 int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0; 2761 int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0;
2762 2762
2763 ASSERT_EQ(object.code(), InstanceofStub::left().code()); 2763 DCHECK_EQ(object.code(), InstanceofStub::left().code());
2764 ASSERT_EQ(function.code(), InstanceofStub::right().code()); 2764 DCHECK_EQ(function.code(), InstanceofStub::right().code());
2765 2765
2766 // Get the object and function - they are always both needed. 2766 // Get the object and function - they are always both needed.
2767 // Go slow case if the object is a smi. 2767 // Go slow case if the object is a smi.
2768 Label slow; 2768 Label slow;
2769 StackArgumentsAccessor args(rsp, 2 + extra_argument_offset, 2769 StackArgumentsAccessor args(rsp, 2 + extra_argument_offset,
2770 ARGUMENTS_DONT_CONTAIN_RECEIVER); 2770 ARGUMENTS_DONT_CONTAIN_RECEIVER);
2771 if (!HasArgsInRegisters()) { 2771 if (!HasArgsInRegisters()) {
2772 __ movp(object, args.GetArgumentOperand(0)); 2772 __ movp(object, args.GetArgumentOperand(0));
2773 __ movp(function, args.GetArgumentOperand(1)); 2773 __ movp(function, args.GetArgumentOperand(1));
2774 } 2774 }
(...skipping 30 matching lines...) Expand all
2805 __ j(above, &slow); 2805 __ j(above, &slow);
2806 2806
2807 // Update the global instanceof or call site inlined cache with the current 2807 // Update the global instanceof or call site inlined cache with the current
2808 // map and function. The cached answer will be set when it is known below. 2808 // map and function. The cached answer will be set when it is known below.
2809 if (!HasCallSiteInlineCheck()) { 2809 if (!HasCallSiteInlineCheck()) {
2810 __ StoreRoot(function, Heap::kInstanceofCacheFunctionRootIndex); 2810 __ StoreRoot(function, Heap::kInstanceofCacheFunctionRootIndex);
2811 __ StoreRoot(map, Heap::kInstanceofCacheMapRootIndex); 2811 __ StoreRoot(map, Heap::kInstanceofCacheMapRootIndex);
2812 } else { 2812 } else {
2813 // The constants for the code patching are based on push instructions 2813 // The constants for the code patching are based on push instructions
2814 // at the call site. 2814 // at the call site.
2815 ASSERT(!HasArgsInRegisters()); 2815 DCHECK(!HasArgsInRegisters());
2816 // Get return address and delta to inlined map check. 2816 // Get return address and delta to inlined map check.
2817 __ movq(kScratchRegister, StackOperandForReturnAddress(0)); 2817 __ movq(kScratchRegister, StackOperandForReturnAddress(0));
2818 __ subp(kScratchRegister, args.GetArgumentOperand(2)); 2818 __ subp(kScratchRegister, args.GetArgumentOperand(2));
2819 if (FLAG_debug_code) { 2819 if (FLAG_debug_code) {
2820 __ movl(scratch, Immediate(kWordBeforeMapCheckValue)); 2820 __ movl(scratch, Immediate(kWordBeforeMapCheckValue));
2821 __ cmpl(Operand(kScratchRegister, kOffsetToMapCheckValue - 4), scratch); 2821 __ cmpl(Operand(kScratchRegister, kOffsetToMapCheckValue - 4), scratch);
2822 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheCheck); 2822 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheCheck);
2823 } 2823 }
2824 __ movp(kScratchRegister, 2824 __ movp(kScratchRegister,
2825 Operand(kScratchRegister, kOffsetToMapCheckValue)); 2825 Operand(kScratchRegister, kOffsetToMapCheckValue));
(...skipping 22 matching lines...) Expand all
2848 STATIC_ASSERT(kSmiTag == 0); 2848 STATIC_ASSERT(kSmiTag == 0);
2849 __ StoreRoot(rax, Heap::kInstanceofCacheAnswerRootIndex); 2849 __ StoreRoot(rax, Heap::kInstanceofCacheAnswerRootIndex);
2850 if (ReturnTrueFalseObject()) { 2850 if (ReturnTrueFalseObject()) {
2851 __ LoadRoot(rax, Heap::kTrueValueRootIndex); 2851 __ LoadRoot(rax, Heap::kTrueValueRootIndex);
2852 } 2852 }
2853 } else { 2853 } else {
2854 // Store offset of true in the root array at the inline check site. 2854 // Store offset of true in the root array at the inline check site.
2855 int true_offset = 0x100 + 2855 int true_offset = 0x100 +
2856 (Heap::kTrueValueRootIndex << kPointerSizeLog2) - kRootRegisterBias; 2856 (Heap::kTrueValueRootIndex << kPointerSizeLog2) - kRootRegisterBias;
2857 // Assert it is a 1-byte signed value. 2857 // Assert it is a 1-byte signed value.
2858 ASSERT(true_offset >= 0 && true_offset < 0x100); 2858 DCHECK(true_offset >= 0 && true_offset < 0x100);
2859 __ movl(rax, Immediate(true_offset)); 2859 __ movl(rax, Immediate(true_offset));
2860 __ movq(kScratchRegister, StackOperandForReturnAddress(0)); 2860 __ movq(kScratchRegister, StackOperandForReturnAddress(0));
2861 __ subp(kScratchRegister, args.GetArgumentOperand(2)); 2861 __ subp(kScratchRegister, args.GetArgumentOperand(2));
2862 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax); 2862 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
2863 if (FLAG_debug_code) { 2863 if (FLAG_debug_code) {
2864 __ movl(rax, Immediate(kWordBeforeResultValue)); 2864 __ movl(rax, Immediate(kWordBeforeResultValue));
2865 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax); 2865 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax);
2866 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); 2866 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov);
2867 } 2867 }
2868 if (!ReturnTrueFalseObject()) { 2868 if (!ReturnTrueFalseObject()) {
2869 __ Set(rax, 0); 2869 __ Set(rax, 0);
2870 } 2870 }
2871 } 2871 }
2872 __ ret(((HasArgsInRegisters() ? 0 : 2) + extra_argument_offset) * 2872 __ ret(((HasArgsInRegisters() ? 0 : 2) + extra_argument_offset) *
2873 kPointerSize); 2873 kPointerSize);
2874 2874
2875 __ bind(&is_not_instance); 2875 __ bind(&is_not_instance);
2876 if (!HasCallSiteInlineCheck()) { 2876 if (!HasCallSiteInlineCheck()) {
2877 // We have to store a non-zero value in the cache. 2877 // We have to store a non-zero value in the cache.
2878 __ StoreRoot(kScratchRegister, Heap::kInstanceofCacheAnswerRootIndex); 2878 __ StoreRoot(kScratchRegister, Heap::kInstanceofCacheAnswerRootIndex);
2879 if (ReturnTrueFalseObject()) { 2879 if (ReturnTrueFalseObject()) {
2880 __ LoadRoot(rax, Heap::kFalseValueRootIndex); 2880 __ LoadRoot(rax, Heap::kFalseValueRootIndex);
2881 } 2881 }
2882 } else { 2882 } else {
2883 // Store offset of false in the root array at the inline check site. 2883 // Store offset of false in the root array at the inline check site.
2884 int false_offset = 0x100 + 2884 int false_offset = 0x100 +
2885 (Heap::kFalseValueRootIndex << kPointerSizeLog2) - kRootRegisterBias; 2885 (Heap::kFalseValueRootIndex << kPointerSizeLog2) - kRootRegisterBias;
2886 // Assert it is a 1-byte signed value. 2886 // Assert it is a 1-byte signed value.
2887 ASSERT(false_offset >= 0 && false_offset < 0x100); 2887 DCHECK(false_offset >= 0 && false_offset < 0x100);
2888 __ movl(rax, Immediate(false_offset)); 2888 __ movl(rax, Immediate(false_offset));
2889 __ movq(kScratchRegister, StackOperandForReturnAddress(0)); 2889 __ movq(kScratchRegister, StackOperandForReturnAddress(0));
2890 __ subp(kScratchRegister, args.GetArgumentOperand(2)); 2890 __ subp(kScratchRegister, args.GetArgumentOperand(2));
2891 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax); 2891 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
2892 if (FLAG_debug_code) { 2892 if (FLAG_debug_code) {
2893 __ movl(rax, Immediate(kWordBeforeResultValue)); 2893 __ movl(rax, Immediate(kWordBeforeResultValue));
2894 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax); 2894 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax);
2895 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); 2895 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov);
2896 } 2896 }
2897 } 2897 }
2898 __ ret(((HasArgsInRegisters() ? 0 : 2) + extra_argument_offset) * 2898 __ ret(((HasArgsInRegisters() ? 0 : 2) + extra_argument_offset) *
2899 kPointerSize); 2899 kPointerSize);
2900 2900
2901 // Slow-case: Go through the JavaScript implementation. 2901 // Slow-case: Go through the JavaScript implementation.
2902 __ bind(&slow); 2902 __ bind(&slow);
2903 if (!ReturnTrueFalseObject()) { 2903 if (!ReturnTrueFalseObject()) {
2904 // Tail call the builtin which returns 0 or 1. 2904 // Tail call the builtin which returns 0 or 1.
2905 ASSERT(!HasArgsInRegisters()); 2905 DCHECK(!HasArgsInRegisters());
2906 if (HasCallSiteInlineCheck()) { 2906 if (HasCallSiteInlineCheck()) {
2907 // Remove extra value from the stack. 2907 // Remove extra value from the stack.
2908 __ PopReturnAddressTo(rcx); 2908 __ PopReturnAddressTo(rcx);
2909 __ Pop(rax); 2909 __ Pop(rax);
2910 __ PushReturnAddressFrom(rcx); 2910 __ PushReturnAddressFrom(rcx);
2911 } 2911 }
2912 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 2912 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
2913 } else { 2913 } else {
2914 // Call the builtin and convert 0/1 to true/false. 2914 // Call the builtin and convert 0/1 to true/false.
2915 { 2915 {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2988 __ CheckMap(index_, 2988 __ CheckMap(index_,
2989 factory->heap_number_map(), 2989 factory->heap_number_map(),
2990 index_not_number_, 2990 index_not_number_,
2991 DONT_DO_SMI_CHECK); 2991 DONT_DO_SMI_CHECK);
2992 call_helper.BeforeCall(masm); 2992 call_helper.BeforeCall(masm);
2993 __ Push(object_); 2993 __ Push(object_);
2994 __ Push(index_); // Consumed by runtime conversion function. 2994 __ Push(index_); // Consumed by runtime conversion function.
2995 if (index_flags_ == STRING_INDEX_IS_NUMBER) { 2995 if (index_flags_ == STRING_INDEX_IS_NUMBER) {
2996 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); 2996 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
2997 } else { 2997 } else {
2998 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); 2998 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX);
2999 // NumberToSmi discards numbers that are not exact integers. 2999 // NumberToSmi discards numbers that are not exact integers.
3000 __ CallRuntime(Runtime::kNumberToSmi, 1); 3000 __ CallRuntime(Runtime::kNumberToSmi, 1);
3001 } 3001 }
3002 if (!index_.is(rax)) { 3002 if (!index_.is(rax)) {
3003 // Save the conversion result before the pop instructions below 3003 // Save the conversion result before the pop instructions below
3004 // have a chance to overwrite it. 3004 // have a chance to overwrite it.
3005 __ movp(index_, rax); 3005 __ movp(index_, rax);
3006 } 3006 }
3007 __ Pop(object_); 3007 __ Pop(object_);
3008 // Reload the instance type. 3008 // Reload the instance type.
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
3589 } 3589 }
3590 3590
3591 // Tail call into the stub that handles binary operations with allocation 3591 // Tail call into the stub that handles binary operations with allocation
3592 // sites. 3592 // sites.
3593 BinaryOpWithAllocationSiteStub stub(isolate(), state_); 3593 BinaryOpWithAllocationSiteStub stub(isolate(), state_);
3594 __ TailCallStub(&stub); 3594 __ TailCallStub(&stub);
3595 } 3595 }
3596 3596
3597 3597
3598 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { 3598 void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
3599 ASSERT(state_ == CompareIC::SMI); 3599 DCHECK(state_ == CompareIC::SMI);
3600 Label miss; 3600 Label miss;
3601 __ JumpIfNotBothSmi(rdx, rax, &miss, Label::kNear); 3601 __ JumpIfNotBothSmi(rdx, rax, &miss, Label::kNear);
3602 3602
3603 if (GetCondition() == equal) { 3603 if (GetCondition() == equal) {
3604 // For equality we do not care about the sign of the result. 3604 // For equality we do not care about the sign of the result.
3605 __ subp(rax, rdx); 3605 __ subp(rax, rdx);
3606 } else { 3606 } else {
3607 Label done; 3607 Label done;
3608 __ subp(rdx, rax); 3608 __ subp(rdx, rax);
3609 __ j(no_overflow, &done, Label::kNear); 3609 __ j(no_overflow, &done, Label::kNear);
3610 // Correct sign of result in case of overflow. 3610 // Correct sign of result in case of overflow.
3611 __ notp(rdx); 3611 __ notp(rdx);
3612 __ bind(&done); 3612 __ bind(&done);
3613 __ movp(rax, rdx); 3613 __ movp(rax, rdx);
3614 } 3614 }
3615 __ ret(0); 3615 __ ret(0);
3616 3616
3617 __ bind(&miss); 3617 __ bind(&miss);
3618 GenerateMiss(masm); 3618 GenerateMiss(masm);
3619 } 3619 }
3620 3620
3621 3621
3622 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) { 3622 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
3623 ASSERT(state_ == CompareIC::NUMBER); 3623 DCHECK(state_ == CompareIC::NUMBER);
3624 3624
3625 Label generic_stub; 3625 Label generic_stub;
3626 Label unordered, maybe_undefined1, maybe_undefined2; 3626 Label unordered, maybe_undefined1, maybe_undefined2;
3627 Label miss; 3627 Label miss;
3628 3628
3629 if (left_ == CompareIC::SMI) { 3629 if (left_ == CompareIC::SMI) {
3630 __ JumpIfNotSmi(rdx, &miss); 3630 __ JumpIfNotSmi(rdx, &miss);
3631 } 3631 }
3632 if (right_ == CompareIC::SMI) { 3632 if (right_ == CompareIC::SMI) {
3633 __ JumpIfNotSmi(rax, &miss); 3633 __ JumpIfNotSmi(rax, &miss);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
3690 __ Cmp(rdx, isolate()->factory()->undefined_value()); 3690 __ Cmp(rdx, isolate()->factory()->undefined_value());
3691 __ j(equal, &unordered); 3691 __ j(equal, &unordered);
3692 } 3692 }
3693 3693
3694 __ bind(&miss); 3694 __ bind(&miss);
3695 GenerateMiss(masm); 3695 GenerateMiss(masm);
3696 } 3696 }
3697 3697
3698 3698
3699 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { 3699 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) {
3700 ASSERT(state_ == CompareIC::INTERNALIZED_STRING); 3700 DCHECK(state_ == CompareIC::INTERNALIZED_STRING);
3701 ASSERT(GetCondition() == equal); 3701 DCHECK(GetCondition() == equal);
3702 3702
3703 // Registers containing left and right operands respectively. 3703 // Registers containing left and right operands respectively.
3704 Register left = rdx; 3704 Register left = rdx;
3705 Register right = rax; 3705 Register right = rax;
3706 Register tmp1 = rcx; 3706 Register tmp1 = rcx;
3707 Register tmp2 = rbx; 3707 Register tmp2 = rbx;
3708 3708
3709 // Check that both operands are heap objects. 3709 // Check that both operands are heap objects.
3710 Label miss; 3710 Label miss;
3711 Condition cond = masm->CheckEitherSmi(left, right, tmp1); 3711 Condition cond = masm->CheckEitherSmi(left, right, tmp1);
3712 __ j(cond, &miss, Label::kNear); 3712 __ j(cond, &miss, Label::kNear);
3713 3713
3714 // Check that both operands are internalized strings. 3714 // Check that both operands are internalized strings.
3715 __ movp(tmp1, FieldOperand(left, HeapObject::kMapOffset)); 3715 __ movp(tmp1, FieldOperand(left, HeapObject::kMapOffset));
3716 __ movp(tmp2, FieldOperand(right, HeapObject::kMapOffset)); 3716 __ movp(tmp2, FieldOperand(right, HeapObject::kMapOffset));
3717 __ movzxbp(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); 3717 __ movzxbp(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset));
3718 __ movzxbp(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); 3718 __ movzxbp(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset));
3719 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); 3719 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
3720 __ orp(tmp1, tmp2); 3720 __ orp(tmp1, tmp2);
3721 __ testb(tmp1, Immediate(kIsNotStringMask | kIsNotInternalizedMask)); 3721 __ testb(tmp1, Immediate(kIsNotStringMask | kIsNotInternalizedMask));
3722 __ j(not_zero, &miss, Label::kNear); 3722 __ j(not_zero, &miss, Label::kNear);
3723 3723
3724 // Internalized strings are compared by identity. 3724 // Internalized strings are compared by identity.
3725 Label done; 3725 Label done;
3726 __ cmpp(left, right); 3726 __ cmpp(left, right);
3727 // Make sure rax is non-zero. At this point input operands are 3727 // Make sure rax is non-zero. At this point input operands are
3728 // guaranteed to be non-zero. 3728 // guaranteed to be non-zero.
3729 ASSERT(right.is(rax)); 3729 DCHECK(right.is(rax));
3730 __ j(not_equal, &done, Label::kNear); 3730 __ j(not_equal, &done, Label::kNear);
3731 STATIC_ASSERT(EQUAL == 0); 3731 STATIC_ASSERT(EQUAL == 0);
3732 STATIC_ASSERT(kSmiTag == 0); 3732 STATIC_ASSERT(kSmiTag == 0);
3733 __ Move(rax, Smi::FromInt(EQUAL)); 3733 __ Move(rax, Smi::FromInt(EQUAL));
3734 __ bind(&done); 3734 __ bind(&done);
3735 __ ret(0); 3735 __ ret(0);
3736 3736
3737 __ bind(&miss); 3737 __ bind(&miss);
3738 GenerateMiss(masm); 3738 GenerateMiss(masm);
3739 } 3739 }
3740 3740
3741 3741
3742 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { 3742 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) {
3743 ASSERT(state_ == CompareIC::UNIQUE_NAME); 3743 DCHECK(state_ == CompareIC::UNIQUE_NAME);
3744 ASSERT(GetCondition() == equal); 3744 DCHECK(GetCondition() == equal);
3745 3745
3746 // Registers containing left and right operands respectively. 3746 // Registers containing left and right operands respectively.
3747 Register left = rdx; 3747 Register left = rdx;
3748 Register right = rax; 3748 Register right = rax;
3749 Register tmp1 = rcx; 3749 Register tmp1 = rcx;
3750 Register tmp2 = rbx; 3750 Register tmp2 = rbx;
3751 3751
3752 // Check that both operands are heap objects. 3752 // Check that both operands are heap objects.
3753 Label miss; 3753 Label miss;
3754 Condition cond = masm->CheckEitherSmi(left, right, tmp1); 3754 Condition cond = masm->CheckEitherSmi(left, right, tmp1);
3755 __ j(cond, &miss, Label::kNear); 3755 __ j(cond, &miss, Label::kNear);
3756 3756
3757 // Check that both operands are unique names. This leaves the instance 3757 // Check that both operands are unique names. This leaves the instance
3758 // types loaded in tmp1 and tmp2. 3758 // types loaded in tmp1 and tmp2.
3759 __ movp(tmp1, FieldOperand(left, HeapObject::kMapOffset)); 3759 __ movp(tmp1, FieldOperand(left, HeapObject::kMapOffset));
3760 __ movp(tmp2, FieldOperand(right, HeapObject::kMapOffset)); 3760 __ movp(tmp2, FieldOperand(right, HeapObject::kMapOffset));
3761 __ movzxbp(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); 3761 __ movzxbp(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset));
3762 __ movzxbp(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); 3762 __ movzxbp(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset));
3763 3763
3764 __ JumpIfNotUniqueName(tmp1, &miss, Label::kNear); 3764 __ JumpIfNotUniqueName(tmp1, &miss, Label::kNear);
3765 __ JumpIfNotUniqueName(tmp2, &miss, Label::kNear); 3765 __ JumpIfNotUniqueName(tmp2, &miss, Label::kNear);
3766 3766
3767 // Unique names are compared by identity. 3767 // Unique names are compared by identity.
3768 Label done; 3768 Label done;
3769 __ cmpp(left, right); 3769 __ cmpp(left, right);
3770 // Make sure rax is non-zero. At this point input operands are 3770 // Make sure rax is non-zero. At this point input operands are
3771 // guaranteed to be non-zero. 3771 // guaranteed to be non-zero.
3772 ASSERT(right.is(rax)); 3772 DCHECK(right.is(rax));
3773 __ j(not_equal, &done, Label::kNear); 3773 __ j(not_equal, &done, Label::kNear);
3774 STATIC_ASSERT(EQUAL == 0); 3774 STATIC_ASSERT(EQUAL == 0);
3775 STATIC_ASSERT(kSmiTag == 0); 3775 STATIC_ASSERT(kSmiTag == 0);
3776 __ Move(rax, Smi::FromInt(EQUAL)); 3776 __ Move(rax, Smi::FromInt(EQUAL));
3777 __ bind(&done); 3777 __ bind(&done);
3778 __ ret(0); 3778 __ ret(0);
3779 3779
3780 __ bind(&miss); 3780 __ bind(&miss);
3781 GenerateMiss(masm); 3781 GenerateMiss(masm);
3782 } 3782 }
3783 3783
3784 3784
3785 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { 3785 void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
3786 ASSERT(state_ == CompareIC::STRING); 3786 DCHECK(state_ == CompareIC::STRING);
3787 Label miss; 3787 Label miss;
3788 3788
3789 bool equality = Token::IsEqualityOp(op_); 3789 bool equality = Token::IsEqualityOp(op_);
3790 3790
3791 // Registers containing left and right operands respectively. 3791 // Registers containing left and right operands respectively.
3792 Register left = rdx; 3792 Register left = rdx;
3793 Register right = rax; 3793 Register right = rax;
3794 Register tmp1 = rcx; 3794 Register tmp1 = rcx;
3795 Register tmp2 = rbx; 3795 Register tmp2 = rbx;
3796 Register tmp3 = rdi; 3796 Register tmp3 = rdi;
(...skipping 30 matching lines...) Expand all
3827 // because we already know they are not identical. We also know they are both 3827 // because we already know they are not identical. We also know they are both
3828 // strings. 3828 // strings.
3829 if (equality) { 3829 if (equality) {
3830 Label do_compare; 3830 Label do_compare;
3831 STATIC_ASSERT(kInternalizedTag == 0); 3831 STATIC_ASSERT(kInternalizedTag == 0);
3832 __ orp(tmp1, tmp2); 3832 __ orp(tmp1, tmp2);
3833 __ testb(tmp1, Immediate(kIsNotInternalizedMask)); 3833 __ testb(tmp1, Immediate(kIsNotInternalizedMask));
3834 __ j(not_zero, &do_compare, Label::kNear); 3834 __ j(not_zero, &do_compare, Label::kNear);
3835 // Make sure rax is non-zero. At this point input operands are 3835 // Make sure rax is non-zero. At this point input operands are
3836 // guaranteed to be non-zero. 3836 // guaranteed to be non-zero.
3837 ASSERT(right.is(rax)); 3837 DCHECK(right.is(rax));
3838 __ ret(0); 3838 __ ret(0);
3839 __ bind(&do_compare); 3839 __ bind(&do_compare);
3840 } 3840 }
3841 3841
3842 // Check that both strings are sequential ASCII. 3842 // Check that both strings are sequential ASCII.
3843 Label runtime; 3843 Label runtime;
3844 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); 3844 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime);
3845 3845
3846 // Compare flat ASCII strings. Returns when done. 3846 // Compare flat ASCII strings. Returns when done.
3847 if (equality) { 3847 if (equality) {
(...skipping 15 matching lines...) Expand all
3863 } else { 3863 } else {
3864 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3864 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3865 } 3865 }
3866 3866
3867 __ bind(&miss); 3867 __ bind(&miss);
3868 GenerateMiss(masm); 3868 GenerateMiss(masm);
3869 } 3869 }
3870 3870
3871 3871
3872 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { 3872 void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
3873 ASSERT(state_ == CompareIC::OBJECT); 3873 DCHECK(state_ == CompareIC::OBJECT);
3874 Label miss; 3874 Label miss;
3875 Condition either_smi = masm->CheckEitherSmi(rdx, rax); 3875 Condition either_smi = masm->CheckEitherSmi(rdx, rax);
3876 __ j(either_smi, &miss, Label::kNear); 3876 __ j(either_smi, &miss, Label::kNear);
3877 3877
3878 __ CmpObjectType(rax, JS_OBJECT_TYPE, rcx); 3878 __ CmpObjectType(rax, JS_OBJECT_TYPE, rcx);
3879 __ j(not_equal, &miss, Label::kNear); 3879 __ j(not_equal, &miss, Label::kNear);
3880 __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx); 3880 __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx);
3881 __ j(not_equal, &miss, Label::kNear); 3881 __ j(not_equal, &miss, Label::kNear);
3882 3882
3883 ASSERT(GetCondition() == equal); 3883 DCHECK(GetCondition() == equal);
3884 __ subp(rax, rdx); 3884 __ subp(rax, rdx);
3885 __ ret(0); 3885 __ ret(0);
3886 3886
3887 __ bind(&miss); 3887 __ bind(&miss);
3888 GenerateMiss(masm); 3888 GenerateMiss(masm);
3889 } 3889 }
3890 3890
3891 3891
3892 void ICCompareStub::GenerateKnownObjects(MacroAssembler* masm) { 3892 void ICCompareStub::GenerateKnownObjects(MacroAssembler* masm) {
3893 Label miss; 3893 Label miss;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3933 __ jmp(rdi); 3933 __ jmp(rdi);
3934 } 3934 }
3935 3935
3936 3936
3937 void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, 3937 void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
3938 Label* miss, 3938 Label* miss,
3939 Label* done, 3939 Label* done,
3940 Register properties, 3940 Register properties,
3941 Handle<Name> name, 3941 Handle<Name> name,
3942 Register r0) { 3942 Register r0) {
3943 ASSERT(name->IsUniqueName()); 3943 DCHECK(name->IsUniqueName());
3944 // If names of slots in range from 1 to kProbes - 1 for the hash value are 3944 // If names of slots in range from 1 to kProbes - 1 for the hash value are
3945 // not equal to the name and kProbes-th slot is not used (its name is the 3945 // not equal to the name and kProbes-th slot is not used (its name is the
3946 // undefined value), it guarantees the hash table doesn't contain the 3946 // undefined value), it guarantees the hash table doesn't contain the
3947 // property. It's true even if some slots represent deleted properties 3947 // property. It's true even if some slots represent deleted properties
3948 // (their names are the hole value). 3948 // (their names are the hole value).
3949 for (int i = 0; i < kInlinedProbes; i++) { 3949 for (int i = 0; i < kInlinedProbes; i++) {
3950 // r0 points to properties hash. 3950 // r0 points to properties hash.
3951 // Compute the masked index: (hash + i + i * i) & mask. 3951 // Compute the masked index: (hash + i + i * i) & mask.
3952 Register index = r0; 3952 Register index = r0;
3953 // Capacity is smi 2^n. 3953 // Capacity is smi 2^n.
3954 __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset)); 3954 __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset));
3955 __ decl(index); 3955 __ decl(index);
3956 __ andp(index, 3956 __ andp(index,
3957 Immediate(name->Hash() + NameDictionary::GetProbeOffset(i))); 3957 Immediate(name->Hash() + NameDictionary::GetProbeOffset(i)));
3958 3958
3959 // Scale the index by multiplying by the entry size. 3959 // Scale the index by multiplying by the entry size.
3960 ASSERT(NameDictionary::kEntrySize == 3); 3960 DCHECK(NameDictionary::kEntrySize == 3);
3961 __ leap(index, Operand(index, index, times_2, 0)); // index *= 3. 3961 __ leap(index, Operand(index, index, times_2, 0)); // index *= 3.
3962 3962
3963 Register entity_name = r0; 3963 Register entity_name = r0;
3964 // Having undefined at this place means the name is not contained. 3964 // Having undefined at this place means the name is not contained.
3965 ASSERT_EQ(kSmiTagSize, 1); 3965 DCHECK_EQ(kSmiTagSize, 1);
3966 __ movp(entity_name, Operand(properties, 3966 __ movp(entity_name, Operand(properties,
3967 index, 3967 index,
3968 times_pointer_size, 3968 times_pointer_size,
3969 kElementsStartOffset - kHeapObjectTag)); 3969 kElementsStartOffset - kHeapObjectTag));
3970 __ Cmp(entity_name, masm->isolate()->factory()->undefined_value()); 3970 __ Cmp(entity_name, masm->isolate()->factory()->undefined_value());
3971 __ j(equal, done); 3971 __ j(equal, done);
3972 3972
3973 // Stop if found the property. 3973 // Stop if found the property.
3974 __ Cmp(entity_name, Handle<Name>(name)); 3974 __ Cmp(entity_name, Handle<Name>(name));
3975 __ j(equal, miss); 3975 __ j(equal, miss);
(...skipping 25 matching lines...) Expand all
4001 // |done| label if a property with the given name is found leaving the 4001 // |done| label if a property with the given name is found leaving the
4002 // index into the dictionary in |r1|. Jump to the |miss| label 4002 // index into the dictionary in |r1|. Jump to the |miss| label
4003 // otherwise. 4003 // otherwise.
4004 void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, 4004 void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
4005 Label* miss, 4005 Label* miss,
4006 Label* done, 4006 Label* done,
4007 Register elements, 4007 Register elements,
4008 Register name, 4008 Register name,
4009 Register r0, 4009 Register r0,
4010 Register r1) { 4010 Register r1) {
4011 ASSERT(!elements.is(r0)); 4011 DCHECK(!elements.is(r0));
4012 ASSERT(!elements.is(r1)); 4012 DCHECK(!elements.is(r1));
4013 ASSERT(!name.is(r0)); 4013 DCHECK(!name.is(r0));
4014 ASSERT(!name.is(r1)); 4014 DCHECK(!name.is(r1));
4015 4015
4016 __ AssertName(name); 4016 __ AssertName(name);
4017 4017
4018 __ SmiToInteger32(r0, FieldOperand(elements, kCapacityOffset)); 4018 __ SmiToInteger32(r0, FieldOperand(elements, kCapacityOffset));
4019 __ decl(r0); 4019 __ decl(r0);
4020 4020
4021 for (int i = 0; i < kInlinedProbes; i++) { 4021 for (int i = 0; i < kInlinedProbes; i++) {
4022 // Compute the masked index: (hash + i + i * i) & mask. 4022 // Compute the masked index: (hash + i + i * i) & mask.
4023 __ movl(r1, FieldOperand(name, Name::kHashFieldOffset)); 4023 __ movl(r1, FieldOperand(name, Name::kHashFieldOffset));
4024 __ shrl(r1, Immediate(Name::kHashShift)); 4024 __ shrl(r1, Immediate(Name::kHashShift));
4025 if (i > 0) { 4025 if (i > 0) {
4026 __ addl(r1, Immediate(NameDictionary::GetProbeOffset(i))); 4026 __ addl(r1, Immediate(NameDictionary::GetProbeOffset(i)));
4027 } 4027 }
4028 __ andp(r1, r0); 4028 __ andp(r1, r0);
4029 4029
4030 // Scale the index by multiplying by the entry size. 4030 // Scale the index by multiplying by the entry size.
4031 ASSERT(NameDictionary::kEntrySize == 3); 4031 DCHECK(NameDictionary::kEntrySize == 3);
4032 __ leap(r1, Operand(r1, r1, times_2, 0)); // r1 = r1 * 3 4032 __ leap(r1, Operand(r1, r1, times_2, 0)); // r1 = r1 * 3
4033 4033
4034 // Check if the key is identical to the name. 4034 // Check if the key is identical to the name.
4035 __ cmpp(name, Operand(elements, r1, times_pointer_size, 4035 __ cmpp(name, Operand(elements, r1, times_pointer_size,
4036 kElementsStartOffset - kHeapObjectTag)); 4036 kElementsStartOffset - kHeapObjectTag));
4037 __ j(equal, done); 4037 __ j(equal, done);
4038 } 4038 }
4039 4039
4040 NameDictionaryLookupStub stub(masm->isolate(), elements, r0, r1, 4040 NameDictionaryLookupStub stub(masm->isolate(), elements, r0, r1,
4041 POSITIVE_LOOKUP); 4041 POSITIVE_LOOKUP);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4083 kPointerSize); 4083 kPointerSize);
4084 for (int i = kInlinedProbes; i < kTotalProbes; i++) { 4084 for (int i = kInlinedProbes; i < kTotalProbes; i++) {
4085 // Compute the masked index: (hash + i + i * i) & mask. 4085 // Compute the masked index: (hash + i + i * i) & mask.
4086 __ movp(scratch, args.GetArgumentOperand(1)); 4086 __ movp(scratch, args.GetArgumentOperand(1));
4087 if (i > 0) { 4087 if (i > 0) {
4088 __ addl(scratch, Immediate(NameDictionary::GetProbeOffset(i))); 4088 __ addl(scratch, Immediate(NameDictionary::GetProbeOffset(i)));
4089 } 4089 }
4090 __ andp(scratch, Operand(rsp, 0)); 4090 __ andp(scratch, Operand(rsp, 0));
4091 4091
4092 // Scale the index by multiplying by the entry size. 4092 // Scale the index by multiplying by the entry size.
4093 ASSERT(NameDictionary::kEntrySize == 3); 4093 DCHECK(NameDictionary::kEntrySize == 3);
4094 __ leap(index_, Operand(scratch, scratch, times_2, 0)); // index *= 3. 4094 __ leap(index_, Operand(scratch, scratch, times_2, 0)); // index *= 3.
4095 4095
4096 // Having undefined at this place means the name is not contained. 4096 // Having undefined at this place means the name is not contained.
4097 __ movp(scratch, Operand(dictionary_, 4097 __ movp(scratch, Operand(dictionary_,
4098 index_, 4098 index_,
4099 times_pointer_size, 4099 times_pointer_size,
4100 kElementsStartOffset - kHeapObjectTag)); 4100 kElementsStartOffset - kHeapObjectTag));
4101 4101
4102 __ Cmp(scratch, isolate()->factory()->undefined_value()); 4102 __ Cmp(scratch, isolate()->factory()->undefined_value());
4103 __ j(equal, &not_in_dictionary); 4103 __ j(equal, &not_in_dictionary);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
4225 InformIncrementalMarker(masm); 4225 InformIncrementalMarker(masm);
4226 regs_.Restore(masm); 4226 regs_.Restore(masm);
4227 __ ret(0); 4227 __ ret(0);
4228 } 4228 }
4229 4229
4230 4230
4231 void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) { 4231 void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
4232 regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_); 4232 regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_);
4233 Register address = 4233 Register address =
4234 arg_reg_1.is(regs_.address()) ? kScratchRegister : regs_.address(); 4234 arg_reg_1.is(regs_.address()) ? kScratchRegister : regs_.address();
4235 ASSERT(!address.is(regs_.object())); 4235 DCHECK(!address.is(regs_.object()));
4236 ASSERT(!address.is(arg_reg_1)); 4236 DCHECK(!address.is(arg_reg_1));
4237 __ Move(address, regs_.address()); 4237 __ Move(address, regs_.address());
4238 __ Move(arg_reg_1, regs_.object()); 4238 __ Move(arg_reg_1, regs_.object());
4239 // TODO(gc) Can we just set address arg2 in the beginning? 4239 // TODO(gc) Can we just set address arg2 in the beginning?
4240 __ Move(arg_reg_2, address); 4240 __ Move(arg_reg_2, address);
4241 __ LoadAddress(arg_reg_3, 4241 __ LoadAddress(arg_reg_3,
4242 ExternalReference::isolate_address(isolate())); 4242 ExternalReference::isolate_address(isolate()));
4243 int argument_count = 3; 4243 int argument_count = 3;
4244 4244
4245 AllowExternalCallThatCantCauseGC scope(masm); 4245 AllowExternalCallThatCantCauseGC scope(masm);
4246 __ PrepareCallCFunction(argument_count); 4246 __ PrepareCallCFunction(argument_count);
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
4517 // rax - number of arguments 4517 // rax - number of arguments
4518 // rdi - constructor? 4518 // rdi - constructor?
4519 // rsp[0] - return address 4519 // rsp[0] - return address
4520 // rsp[8] - last argument 4520 // rsp[8] - last argument
4521 Handle<Object> undefined_sentinel( 4521 Handle<Object> undefined_sentinel(
4522 masm->isolate()->heap()->undefined_value(), 4522 masm->isolate()->heap()->undefined_value(),
4523 masm->isolate()); 4523 masm->isolate());
4524 4524
4525 Label normal_sequence; 4525 Label normal_sequence;
4526 if (mode == DONT_OVERRIDE) { 4526 if (mode == DONT_OVERRIDE) {
4527 ASSERT(FAST_SMI_ELEMENTS == 0); 4527 DCHECK(FAST_SMI_ELEMENTS == 0);
4528 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 4528 DCHECK(FAST_HOLEY_SMI_ELEMENTS == 1);
4529 ASSERT(FAST_ELEMENTS == 2); 4529 DCHECK(FAST_ELEMENTS == 2);
4530 ASSERT(FAST_HOLEY_ELEMENTS == 3); 4530 DCHECK(FAST_HOLEY_ELEMENTS == 3);
4531 ASSERT(FAST_DOUBLE_ELEMENTS == 4); 4531 DCHECK(FAST_DOUBLE_ELEMENTS == 4);
4532 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); 4532 DCHECK(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
4533 4533
4534 // is the low bit set? If so, we are holey and that is good. 4534 // is the low bit set? If so, we are holey and that is good.
4535 __ testb(rdx, Immediate(1)); 4535 __ testb(rdx, Immediate(1));
4536 __ j(not_zero, &normal_sequence); 4536 __ j(not_zero, &normal_sequence);
4537 } 4537 }
4538 4538
4539 // look at the first argument 4539 // look at the first argument
4540 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); 4540 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
4541 __ movp(rcx, args.GetArgumentOperand(0)); 4541 __ movp(rcx, args.GetArgumentOperand(0));
4542 __ testp(rcx, rcx); 4542 __ testp(rcx, rcx);
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
4881 #if defined(__MINGW64__) || defined(_WIN64) 4881 #if defined(__MINGW64__) || defined(_WIN64)
4882 Register arguments_arg = rcx; 4882 Register arguments_arg = rcx;
4883 Register callback_arg = rdx; 4883 Register callback_arg = rdx;
4884 #else 4884 #else
4885 Register arguments_arg = rdi; 4885 Register arguments_arg = rdi;
4886 Register callback_arg = rsi; 4886 Register callback_arg = rsi;
4887 #endif 4887 #endif
4888 4888
4889 // It's okay if api_function_address == callback_arg 4889 // It's okay if api_function_address == callback_arg
4890 // but not arguments_arg 4890 // but not arguments_arg
4891 ASSERT(!api_function_address.is(arguments_arg)); 4891 DCHECK(!api_function_address.is(arguments_arg));
4892 4892
4893 // v8::InvocationCallback's argument. 4893 // v8::InvocationCallback's argument.
4894 __ leap(arguments_arg, StackSpaceOperand(0)); 4894 __ leap(arguments_arg, StackSpaceOperand(0));
4895 4895
4896 ExternalReference thunk_ref = 4896 ExternalReference thunk_ref =
4897 ExternalReference::invoke_function_callback(isolate()); 4897 ExternalReference::invoke_function_callback(isolate());
4898 4898
4899 // Accessor for FunctionCallbackInfo and first js arg. 4899 // Accessor for FunctionCallbackInfo and first js arg.
4900 StackArgumentsAccessor args_from_rbp(rbp, FCA::kArgsLength + 1, 4900 StackArgumentsAccessor args_from_rbp(rbp, FCA::kArgsLength + 1,
4901 ARGUMENTS_DONT_CONTAIN_RECEIVER); 4901 ARGUMENTS_DONT_CONTAIN_RECEIVER);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4951 4951
4952 // The context register (rsi) has been saved in PrepareCallApiFunction and 4952 // The context register (rsi) has been saved in PrepareCallApiFunction and
4953 // could be used to pass arguments. 4953 // could be used to pass arguments.
4954 __ leap(accessor_info_arg, StackSpaceOperand(0)); 4954 __ leap(accessor_info_arg, StackSpaceOperand(0));
4955 4955
4956 ExternalReference thunk_ref = 4956 ExternalReference thunk_ref =
4957 ExternalReference::invoke_accessor_getter_callback(isolate()); 4957 ExternalReference::invoke_accessor_getter_callback(isolate());
4958 4958
4959 // It's okay if api_function_address == getter_arg 4959 // It's okay if api_function_address == getter_arg
4960 // but not accessor_info_arg or name_arg 4960 // but not accessor_info_arg or name_arg
4961 ASSERT(!api_function_address.is(accessor_info_arg) && 4961 DCHECK(!api_function_address.is(accessor_info_arg) &&
4962 !api_function_address.is(name_arg)); 4962 !api_function_address.is(name_arg));
4963 4963
4964 // The name handler is counted as an argument. 4964 // The name handler is counted as an argument.
4965 StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength); 4965 StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength);
4966 Operand return_value_operand = args.GetArgumentOperand( 4966 Operand return_value_operand = args.GetArgumentOperand(
4967 PropertyCallbackArguments::kArgsLength - 1 - 4967 PropertyCallbackArguments::kArgsLength - 1 -
4968 PropertyCallbackArguments::kReturnValueOffset); 4968 PropertyCallbackArguments::kReturnValueOffset);
4969 __ CallApiFunctionAndReturn(api_function_address, 4969 __ CallApiFunctionAndReturn(api_function_address,
4970 thunk_ref, 4970 thunk_ref,
4971 getter_arg, 4971 getter_arg,
4972 kStackSpace, 4972 kStackSpace,
4973 return_value_operand, 4973 return_value_operand,
4974 NULL); 4974 NULL);
4975 } 4975 }
4976 4976
4977 4977
4978 #undef __ 4978 #undef __
4979 4979
4980 } } // namespace v8::internal 4980 } } // namespace v8::internal
4981 4981
4982 #endif // V8_TARGET_ARCH_X64 4982 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | src/x64/codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698