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 |