| Index: src/x64/stub-cache-x64.cc
|
| ===================================================================
|
| --- src/x64/stub-cache-x64.cc (revision 15486)
|
| +++ src/x64/stub-cache-x64.cc (working copy)
|
| @@ -37,6 +37,8 @@
|
| namespace internal {
|
|
|
| #define __ ACCESS_MASM(masm)
|
| +#define __k __
|
| +#define __a __
|
|
|
|
|
| static void ProbeTable(Isolate* isolate,
|
| @@ -50,8 +52,13 @@
|
| Register offset) {
|
| // We need to scale up the pointer by 2 because the offset is scaled by less
|
| // than the pointer size.
|
| +#ifndef V8_TARGET_ARCH_X32
|
| ASSERT(kPointerSizeLog2 == kHeapObjectTagSize + 1);
|
| ScaleFactor scale_factor = times_2;
|
| +#else
|
| + ASSERT(kPointerSizeLog2 == kHeapObjectTagSize);
|
| + ScaleFactor scale_factor = times_1;
|
| +#endif
|
|
|
| ASSERT_EQ(3 * kPointerSize, sizeof(StubCache::Entry));
|
| // The offset register holds the entry offset times four (due to masking
|
| @@ -410,12 +417,12 @@
|
| // -- rsp[0] : return address
|
| // -- rsp[8] : last argument in the internal frame of the caller
|
| // -----------------------------------
|
| - __ movq(scratch, Operand(rsp, 0));
|
| + __k movq(scratch, Operand(rsp, 0));
|
| __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
|
| - __ movq(Operand(rsp, 0), scratch);
|
| + __k movq(Operand(rsp, 0), scratch);
|
| __ Move(scratch, Smi::FromInt(0));
|
| for (int i = 1; i <= kFastApiCallArguments; i++) {
|
| - __ movq(Operand(rsp, i * kPointerSize), scratch);
|
| + __a movq(Operand(rsp, i * kPointerSize), scratch);
|
| }
|
| }
|
|
|
| @@ -431,8 +438,8 @@
|
| // -- rsp[kFastApiCallArguments * 8 + 8] : last argument in the internal
|
| // frame.
|
| // -----------------------------------
|
| - __ movq(scratch, Operand(rsp, 0));
|
| - __ movq(Operand(rsp, kFastApiCallArguments * kPointerSize), scratch);
|
| + __k movq(scratch, Operand(rsp, 0));
|
| + __k movq(Operand(rsp, kFastApiCallArguments * kPointerSize), scratch);
|
| __ addq(rsp, Immediate(kPointerSize * kFastApiCallArguments));
|
| }
|
|
|
| @@ -464,26 +471,31 @@
|
| __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
|
|
|
| // Pass the additional arguments.
|
| - __ movq(Operand(rsp, 2 * kPointerSize), rdi);
|
| + __a movq(Operand(rsp, 2 * kPointerSize), rdi);
|
| Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
|
| Handle<Object> call_data(api_call_info->data(), masm->isolate());
|
| if (masm->isolate()->heap()->InNewSpace(*call_data)) {
|
| __ Move(rcx, api_call_info);
|
| __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
|
| - __ movq(Operand(rsp, 3 * kPointerSize), rbx);
|
| + __a movq(Operand(rsp, 3 * kPointerSize), rbx);
|
| } else {
|
| - __ Move(Operand(rsp, 3 * kPointerSize), call_data);
|
| + __a Move(Operand(rsp, 3 * kPointerSize), call_data);
|
| }
|
| __ movq(kScratchRegister,
|
| ExternalReference::isolate_address(masm->isolate()));
|
| - __ movq(Operand(rsp, 4 * kPointerSize), kScratchRegister);
|
| + __a movq(Operand(rsp, 4 * kPointerSize), kScratchRegister);
|
| __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
|
| - __ movq(Operand(rsp, 5 * kPointerSize), kScratchRegister);
|
| - __ movq(Operand(rsp, 6 * kPointerSize), kScratchRegister);
|
| + __a movq(Operand(rsp, 5 * kPointerSize), kScratchRegister);
|
| + __a movq(Operand(rsp, 6 * kPointerSize), kScratchRegister);
|
|
|
| // Prepare arguments.
|
| STATIC_ASSERT(kFastApiCallArguments == 6);
|
| +#ifndef V8_TARGET_ARCH_X32
|
| __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize));
|
| +#else
|
| + __ leal(rbx, Operand(rsp, 1 * kHWRegSize +
|
| + (kFastApiCallArguments - 1) * kPointerSize));
|
| +#endif
|
|
|
| // Function address is a foreign pointer outside V8's heap.
|
| Address function_address = v8::ToCData<Address>(api_call_info->callback());
|
| @@ -864,11 +876,11 @@
|
| object->map()->unused_property_fields() == 0) {
|
| // The properties must be extended before we can store the value.
|
| // We jump to a runtime call that extends the properties array.
|
| - __ pop(scratch1); // Return address.
|
| + __k pop(scratch1); // Return address.
|
| __ push(receiver_reg);
|
| __ Push(transition);
|
| __ push(value_reg);
|
| - __ push(scratch1);
|
| + __k push(scratch1);
|
| __ TailCallExternalReference(
|
| ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
|
| masm->isolate()),
|
| @@ -1120,7 +1132,7 @@
|
| int depth = 0;
|
|
|
| if (save_at_depth == depth) {
|
| - __ movq(Operand(rsp, kPointerSize), object_reg);
|
| + __a movq(Operand(rsp, 1 * kPointerSize), object_reg);
|
| }
|
|
|
| // Check the maps in the prototype chain.
|
| @@ -1180,7 +1192,7 @@
|
| }
|
|
|
| if (save_at_depth == depth) {
|
| - __ movq(Operand(rsp, kPointerSize), reg);
|
| + __a movq(Operand(rsp, 1 * kPointerSize), reg);
|
| }
|
|
|
| // Go to the next object in the prototype chain.
|
| @@ -1317,7 +1329,7 @@
|
| Handle<ExecutableAccessorInfo> callback) {
|
| // Insert additional parameters into the stack frame above return address.
|
| ASSERT(!scratch4().is(reg));
|
| - __ pop(scratch4()); // Get return address to place it below.
|
| + __k pop(scratch4()); // Get return address to place it below.
|
|
|
| __ push(receiver()); // receiver
|
| __ push(reg); // holder
|
| @@ -1357,7 +1369,7 @@
|
|
|
| ASSERT(!name_arg.is(scratch4()));
|
| __ movq(name_arg, rsp);
|
| - __ push(scratch4()); // Restore return address.
|
| + __k push(scratch4()); // Restore return address.
|
|
|
| // v8::Arguments::values_ and handler for name.
|
| const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1;
|
| @@ -1477,10 +1489,10 @@
|
| } else { // !compile_followup_inline
|
| // Call the runtime system to load the interceptor.
|
| // Check that the maps haven't changed.
|
| - __ pop(scratch2()); // save old return address
|
| + __k pop(scratch2()); // save old return address
|
| PushInterceptorArguments(masm(), receiver(), holder_reg,
|
| this->name(), interceptor_holder);
|
| - __ push(scratch2()); // restore old return address
|
| + __k push(scratch2()); // restore old return address
|
|
|
| ExternalReference ref = ExternalReference(
|
| IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate());
|
| @@ -1507,7 +1519,7 @@
|
| const int argc = arguments().immediate();
|
|
|
| // Get the receiver from the stack.
|
| - __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
|
|
|
|
| // Check that the maps haven't changed.
|
| @@ -1573,7 +1585,7 @@
|
|
|
| // Get the receiver from the stack.
|
| const int argc = arguments().immediate();
|
| - __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
|
|
| // Check that the receiver isn't a smi.
|
| __ JumpIfSmi(rdx, &miss);
|
| @@ -1594,7 +1606,7 @@
|
| // necessary.
|
| if (object->IsGlobalObject()) {
|
| __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
|
| - __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
|
| + __a movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
|
| }
|
|
|
| // Invoke the function.
|
| @@ -1628,7 +1640,7 @@
|
|
|
| if (cell.is_null()) {
|
| // Get the receiver from the stack.
|
| - __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
|
|
| // Check that the receiver isn't a smi.
|
| __ JumpIfSmi(rdx, &miss);
|
| @@ -1682,7 +1694,7 @@
|
|
|
| // Get the receiver from the stack.
|
| const int argc = arguments().immediate();
|
| - __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
|
|
| // Check that the receiver isn't a smi.
|
| __ JumpIfSmi(rdx, &miss);
|
| @@ -1721,7 +1733,7 @@
|
| __ j(greater, &attempt_to_grow_elements);
|
|
|
| // Check if value is a smi.
|
| - __ movq(rcx, Operand(rsp, argc * kPointerSize));
|
| + __a movq(rcx, Operand(rsp, argc * kPointerSize));
|
| __ JumpIfNotSmi(rcx, &with_write_barrier);
|
|
|
| // Save new length.
|
| @@ -1756,7 +1768,7 @@
|
| __ cmpl(rax, rcx);
|
| __ j(greater, &call_builtin);
|
|
|
| - __ movq(rcx, Operand(rsp, argc * kPointerSize));
|
| + __a movq(rcx, Operand(rsp, argc * kPointerSize));
|
| __ StoreNumberToDoubleElements(
|
| rcx, rdi, rax, xmm0, &call_builtin, argc * kDoubleSize);
|
|
|
| @@ -1833,7 +1845,7 @@
|
| __ jmp(&call_builtin);
|
| }
|
|
|
| - __ movq(rbx, Operand(rsp, argc * kPointerSize));
|
| + __a movq(rbx, Operand(rsp, argc * kPointerSize));
|
| // Growing elements that are SMI-only requires special handling in case
|
| // the new element is non-Smi. For now, delegate to the builtin.
|
| Label no_fast_elements_check;
|
| @@ -1882,7 +1894,7 @@
|
| __ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
|
|
|
| // Restore receiver to rdx as finish sequence assumes it's here.
|
| - __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
|
|
| // Increment element's and array's sizes.
|
| __ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset),
|
| @@ -1933,7 +1945,7 @@
|
|
|
| // Get the receiver from the stack.
|
| const int argc = arguments().immediate();
|
| - __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
|
|
| // Check that the receiver isn't a smi.
|
| __ JumpIfSmi(rdx, &miss);
|
| @@ -2036,9 +2048,9 @@
|
| Register receiver = rbx;
|
| Register index = rdi;
|
| Register result = rax;
|
| - __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
|
| if (argc > 0) {
|
| - __ movq(index, Operand(rsp, (argc - 0) * kPointerSize));
|
| + __a movq(index, Operand(rsp, (argc - 0) * kPointerSize));
|
| } else {
|
| __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
|
| }
|
| @@ -2117,9 +2129,9 @@
|
| Register index = rdi;
|
| Register scratch = rdx;
|
| Register result = rax;
|
| - __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
|
| if (argc > 0) {
|
| - __ movq(index, Operand(rsp, (argc - 0) * kPointerSize));
|
| + __a movq(index, Operand(rsp, (argc - 0) * kPointerSize));
|
| } else {
|
| __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
|
| }
|
| @@ -2178,7 +2190,7 @@
|
| GenerateNameCheck(name, &miss);
|
|
|
| if (cell.is_null()) {
|
| - __ movq(rdx, Operand(rsp, 2 * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, 2 * kPointerSize));
|
| __ JumpIfSmi(rdx, &miss);
|
| CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
|
| name, &miss);
|
| @@ -2191,7 +2203,7 @@
|
|
|
| // Load the char code argument.
|
| Register code = rbx;
|
| - __ movq(code, Operand(rsp, 1 * kPointerSize));
|
| + __a movq(code, Operand(rsp, 1 * kPointerSize));
|
|
|
| // Check the code is a smi.
|
| Label slow;
|
| @@ -2262,7 +2274,7 @@
|
| GenerateNameCheck(name, &miss);
|
|
|
| if (cell.is_null()) {
|
| - __ movq(rdx, Operand(rsp, 2 * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, 2 * kPointerSize));
|
| __ JumpIfSmi(rdx, &miss);
|
| CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
|
| name, &miss);
|
| @@ -2273,7 +2285,7 @@
|
| GenerateLoadFunctionFromCell(cell, function, &miss);
|
| }
|
| // Load the (only) argument into rax.
|
| - __ movq(rax, Operand(rsp, 1 * kPointerSize));
|
| + __a movq(rax, Operand(rsp, 1 * kPointerSize));
|
|
|
| // Check if the argument is a smi.
|
| Label not_smi;
|
| @@ -2304,25 +2316,25 @@
|
| // Check if the argument is a heap number and load its value.
|
| __ bind(¬_smi);
|
| __ CheckMap(rax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK);
|
| - __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset));
|
| + __k movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset));
|
|
|
| // Check the sign of the argument. If the argument is positive,
|
| // just return it.
|
| Label negative_sign;
|
| const int sign_mask_shift =
|
| (HeapNumber::kExponentOffset - HeapNumber::kValueOffset) * kBitsPerByte;
|
| - __ movq(rdi, static_cast<int64_t>(HeapNumber::kSignMask) << sign_mask_shift,
|
| + __k movq(rdi, static_cast<int64_t>(HeapNumber::kSignMask) << sign_mask_shift,
|
| RelocInfo::NONE64);
|
| - __ testq(rbx, rdi);
|
| + __k testq(rbx, rdi);
|
| __ j(not_zero, &negative_sign);
|
| __ ret(2 * kPointerSize);
|
|
|
| // If the argument is negative, clear the sign, and return a new
|
| // number. We still have the sign mask in rdi.
|
| __ bind(&negative_sign);
|
| - __ xor_(rbx, rdi);
|
| + __k xor_(rbx, rdi);
|
| __ AllocateHeapNumber(rax, rdx, &slow);
|
| - __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rbx);
|
| + __k movq(FieldOperand(rax, HeapNumber::kValueOffset), rbx);
|
| __ ret(2 * kPointerSize);
|
|
|
| // Tail call the full function. We do not have to patch the receiver
|
| @@ -2366,7 +2378,7 @@
|
|
|
| // Get the receiver from the stack.
|
| const int argc = arguments().immediate();
|
| - __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
|
|
| // Check that the receiver isn't a smi.
|
| __ JumpIfSmi(rdx, &miss_before_stack_reserved);
|
| @@ -2384,8 +2396,8 @@
|
| name, depth, &miss);
|
|
|
| // Move the return address on top of the stack.
|
| - __ movq(rax, Operand(rsp, kFastApiCallArguments * kPointerSize));
|
| - __ movq(Operand(rsp, 0 * kPointerSize), rax);
|
| + __k movq(rax, Operand(rsp, kFastApiCallArguments * kPointerSize));
|
| + __k movq(Operand(rsp, 0 * kPointerSize), rax);
|
|
|
| GenerateFastApiCall(masm(), optimization, argc);
|
|
|
| @@ -2419,7 +2431,7 @@
|
|
|
| // Get the receiver from the stack.
|
| const int argc = arguments().immediate();
|
| - __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
|
|
| // Check that the receiver isn't a smi.
|
| if (check != NUMBER_CHECK) {
|
| @@ -2443,7 +2455,7 @@
|
| // necessary.
|
| if (object->IsGlobalObject()) {
|
| __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
|
| - __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
|
| + __a movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
|
| }
|
| break;
|
|
|
| @@ -2570,14 +2582,14 @@
|
| LookupPostInterceptor(holder, name, &lookup);
|
|
|
| // Get the receiver from the stack.
|
| - __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
|
|
| CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_);
|
| compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax,
|
| &miss);
|
|
|
| // Restore receiver.
|
| - __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| + __a movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
|
|
| // Check that the function really is a function.
|
| __ JumpIfSmi(rax, &miss);
|
| @@ -2588,7 +2600,7 @@
|
| // necessary.
|
| if (object->IsGlobalObject()) {
|
| __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
|
| - __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
|
| + __a movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
|
| }
|
|
|
| // Invoke the function.
|
| @@ -2643,7 +2655,7 @@
|
| // Patch the receiver on the stack with the global proxy.
|
| if (object->IsGlobalObject()) {
|
| __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
|
| - __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
|
| + __a movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
|
| }
|
|
|
| // Set up the context (function already in rdi).
|
| @@ -2687,12 +2699,12 @@
|
| // Stub never generated for non-global objects that require access checks.
|
| ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
|
|
|
| - __ pop(scratch1()); // remove the return address
|
| + __k pop(scratch1()); // remove the return address
|
| __ push(receiver());
|
| __ Push(callback); // callback info
|
| __ push(this->name());
|
| __ push(value());
|
| - __ push(scratch1()); // restore return address
|
| + __k push(scratch1()); // restore return address
|
|
|
| // Do tail-call to the runtime system.
|
| ExternalReference store_callback_property =
|
| @@ -2772,12 +2784,12 @@
|
| // checks.
|
| ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
|
|
|
| - __ pop(scratch1()); // remove the return address
|
| + __k pop(scratch1()); // remove the return address
|
| __ push(receiver());
|
| __ push(this->name());
|
| __ push(value());
|
| __ Push(Smi::FromInt(strict_mode()));
|
| - __ push(scratch1()); // restore return address
|
| + __k push(scratch1()); // restore return address
|
|
|
| // Do tail-call to the runtime system.
|
| ExternalReference store_ic_property =
|
| @@ -3117,6 +3129,10 @@
|
| __ ucomisd(xmm_scratch1, xmm_scratch0);
|
| __ j(not_equal, fail);
|
| __ j(parity_even, fail); // NaN.
|
| +#ifdef V8_TARGET_ARCH_X32
|
| + __ cmpl(scratch, Immediate(0xc0000000));
|
| + __ j(sign, fail);
|
| +#endif
|
| __ Integer32ToSmi(key, scratch);
|
| __ bind(&key_ok);
|
| }
|
| @@ -3245,7 +3261,7 @@
|
| // fails (out-of-range), go into the runtime.
|
| __ cvttsd2siq(r8, xmm0);
|
| __ Set(kScratchRegister, V8_UINT64_C(0x8000000000000000));
|
| - __ cmpq(r8, kScratchRegister);
|
| + __k cmpq(r8, kScratchRegister);
|
| __ j(equal, &slow);
|
|
|
| // rdx: value (converted to an untagged integer)
|
| @@ -3540,9 +3556,9 @@
|
| __ StoreNumberToDoubleElements(rax, rdi, rcx, xmm0,
|
| &restore_key_transition_elements_kind);
|
|
|
| - __ movq(r8, BitCast<int64_t, uint64_t>(kHoleNanInt64), RelocInfo::NONE64);
|
| + __k movq(r8, BitCast<int64_t, uint64_t>(kHoleNanInt64), RelocInfo::NONE64);
|
| for (int i = 1; i < JSArray::kPreallocatedArrayElements; i++) {
|
| - __ movq(FieldOperand(rdi, FixedDoubleArray::OffsetOfElementAt(i)), r8);
|
| + __k movq(FieldOperand(rdi, FixedDoubleArray::OffsetOfElementAt(i)), r8);
|
| }
|
|
|
| // Install the new backing store in the JSArray.
|
| @@ -3574,7 +3590,8 @@
|
| }
|
| }
|
|
|
| -
|
| +#undef __a
|
| +#undef __k
|
| #undef __
|
|
|
| } } // namespace v8::internal
|
|
|