Upgrade to V8 3.3
Merge V8 at 3.3.10.39
Simple merge required updates to makefiles only.
Bug: 5688872
Change-Id: I14703f418235f5ce6013b9b3e2e502407a9f6dfd
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index a549633..fc4581c 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -98,6 +98,7 @@
// Set expected number of arguments to zero (not changing rax).
__ Set(rbx, 0);
__ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
+ __ SetCallKind(rcx, CALL_AS_METHOD);
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
}
@@ -342,11 +343,12 @@
Handle<Code> code =
masm->isolate()->builtins()->HandleApiCallConstruct();
ParameterCount expected(0);
- __ InvokeCode(code, expected, expected,
- RelocInfo::CODE_TARGET, CALL_FUNCTION);
+ __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET,
+ CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
} else {
ParameterCount actual(rax);
- __ InvokeFunction(rdi, actual, CALL_FUNCTION);
+ __ InvokeFunction(rdi, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
// Restore context from the frame.
@@ -498,7 +500,8 @@
} else {
ParameterCount actual(rax);
// Function must be in rdi.
- __ InvokeFunction(rdi, actual, CALL_FUNCTION);
+ __ InvokeFunction(rdi, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
// Exit the JS frame. Notice that this also removes the empty
@@ -526,17 +529,23 @@
// Push a copy of the function onto the stack.
__ push(rdi);
+ // Push call kind information.
+ __ push(rcx);
__ push(rdi); // Function is also the parameter to the runtime call.
__ CallRuntime(Runtime::kLazyCompile, 1);
+
+ // Restore call kind information.
+ __ pop(rcx);
+ // Restore receiver.
__ pop(rdi);
// Tear down temporary frame.
__ LeaveInternalFrame();
// Do a tail-call of the compiled function.
- __ lea(rcx, FieldOperand(rax, Code::kHeaderSize));
- __ jmp(rcx);
+ __ lea(rax, FieldOperand(rax, Code::kHeaderSize));
+ __ jmp(rax);
}
@@ -546,17 +555,23 @@
// Push a copy of the function onto the stack.
__ push(rdi);
+ // Push call kind information.
+ __ push(rcx);
__ push(rdi); // Function is also the parameter to the runtime call.
__ CallRuntime(Runtime::kLazyRecompile, 1);
- // Restore function and tear down temporary frame.
+ // Restore call kind information.
+ __ pop(rcx);
+ // Restore function.
__ pop(rdi);
+
+ // Tear down temporary frame.
__ LeaveInternalFrame();
// Do a tail-call of the compiled function.
- __ lea(rcx, FieldOperand(rax, Code::kHeaderSize));
- __ jmp(rcx);
+ __ lea(rax, FieldOperand(rax, Code::kHeaderSize));
+ __ jmp(rax);
}
@@ -576,15 +591,15 @@
__ SmiToInteger32(rcx, Operand(rsp, 1 * kPointerSize));
// Switch on the state.
- NearLabel not_no_registers, not_tos_rax;
+ Label not_no_registers, not_tos_rax;
__ cmpq(rcx, Immediate(FullCodeGenerator::NO_REGISTERS));
- __ j(not_equal, ¬_no_registers);
+ __ j(not_equal, ¬_no_registers, Label::kNear);
__ ret(1 * kPointerSize); // Remove state.
__ bind(¬_no_registers);
__ movq(rax, Operand(rsp, 2 * kPointerSize));
__ cmpq(rcx, Immediate(FullCodeGenerator::TOS_REG));
- __ j(not_equal, ¬_tos_rax);
+ __ j(not_equal, ¬_tos_rax, Label::kNear);
__ ret(2 * kPointerSize); // Remove state, rax.
__ bind(¬_tos_rax);
@@ -658,19 +673,25 @@
Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte));
__ j(not_equal, &shift_arguments);
+ // Do not transform the receiver for natives.
+ // SharedFunctionInfo is already loaded into rbx.
+ __ testb(FieldOperand(rbx, SharedFunctionInfo::kES5NativeByteOffset),
+ Immediate(1 << SharedFunctionInfo::kES5NativeBitWithinByte));
+ __ j(not_zero, &shift_arguments);
+
// Compute the receiver in non-strict mode.
__ movq(rbx, Operand(rsp, rax, times_pointer_size, 0));
- __ JumpIfSmi(rbx, &convert_to_object);
+ __ JumpIfSmi(rbx, &convert_to_object, Label::kNear);
__ CompareRoot(rbx, Heap::kNullValueRootIndex);
__ j(equal, &use_global_receiver);
__ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
__ j(equal, &use_global_receiver);
+ STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
+ STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
__ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, rcx);
- __ j(below, &convert_to_object);
- __ CmpInstanceType(rcx, LAST_JS_OBJECT_TYPE);
- __ j(below_equal, &shift_arguments);
+ __ j(above_equal, &shift_arguments);
__ bind(&convert_to_object);
__ EnterInternalFrame(); // In order to preserve argument count.
@@ -686,7 +707,7 @@
__ LeaveInternalFrame();
// Restore the function to rdi.
__ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
- __ jmp(&patch_receiver);
+ __ jmp(&patch_receiver, Label::kNear);
// Use the global receiver object from the called function as the
// receiver.
@@ -734,6 +755,7 @@
__ j(not_zero, &function);
__ Set(rbx, 0);
__ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
+ __ SetCallKind(rcx, CALL_AS_METHOD);
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
__ bind(&function);
@@ -747,13 +769,15 @@
FieldOperand(rdx,
SharedFunctionInfo::kFormalParameterCountOffset));
__ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
+ __ SetCallKind(rcx, CALL_AS_METHOD);
__ cmpq(rax, rbx);
__ j(not_equal,
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
ParameterCount expected(0);
- __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION);
+ __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
@@ -822,8 +846,13 @@
Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte));
__ j(not_equal, &push_receiver);
+ // Do not transform the receiver for natives.
+ __ testb(FieldOperand(rdx, SharedFunctionInfo::kES5NativeByteOffset),
+ Immediate(1 << SharedFunctionInfo::kES5NativeBitWithinByte));
+ __ j(not_zero, &push_receiver);
+
// Compute the receiver in non-strict mode.
- __ JumpIfSmi(rbx, &call_to_object);
+ __ JumpIfSmi(rbx, &call_to_object, Label::kNear);
__ CompareRoot(rbx, Heap::kNullValueRootIndex);
__ j(equal, &use_global_receiver);
__ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
@@ -831,17 +860,17 @@
// If given receiver is already a JavaScript object then there's no
// reason for converting it.
+ STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
+ STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
__ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, rcx);
- __ j(below, &call_to_object);
- __ CmpInstanceType(rcx, LAST_JS_OBJECT_TYPE);
- __ j(below_equal, &push_receiver);
+ __ j(above_equal, &push_receiver);
// Convert the receiver to an object.
__ bind(&call_to_object);
__ push(rbx);
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
__ movq(rbx, rax);
- __ jmp(&push_receiver);
+ __ jmp(&push_receiver, Label::kNear);
// Use the current global receiver object as the receiver.
__ bind(&use_global_receiver);
@@ -888,7 +917,8 @@
ParameterCount actual(rax);
__ SmiToInteger32(rax, rax);
__ movq(rdi, Operand(rbp, kFunctionOffset));
- __ InvokeFunction(rdi, actual, CALL_FUNCTION);
+ __ InvokeFunction(rdi, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
__ LeaveInternalFrame();
__ ret(3 * kPointerSize); // remove function, receiver, and arguments
@@ -1324,11 +1354,11 @@
// Push the function on the stack.
__ push(rdi);
- // Preserve the number of arguments on the stack. Must preserve both
- // rax and rbx because these registers are used when copying the
+ // Preserve the number of arguments on the stack. Must preserve rax,
+ // rbx and rcx because these registers are used when copying the
// arguments and the receiver.
- __ Integer32ToSmi(rcx, rax);
- __ push(rcx);
+ __ Integer32ToSmi(r8, rax);
+ __ push(r8);
}
@@ -1352,6 +1382,7 @@
// ----------- S t a t e -------------
// -- rax : actual number of arguments
// -- rbx : expected number of arguments
+ // -- rcx : call kind information
// -- rdx : code entry to call
// -----------------------------------
@@ -1372,14 +1403,14 @@
// Copy receiver and all expected arguments.
const int offset = StandardFrameConstants::kCallerSPOffset;
__ lea(rax, Operand(rbp, rax, times_pointer_size, offset));
- __ Set(rcx, -1); // account for receiver
+ __ Set(r8, -1); // account for receiver
Label copy;
__ bind(©);
- __ incq(rcx);
+ __ incq(r8);
__ push(Operand(rax, 0));
__ subq(rax, Immediate(kPointerSize));
- __ cmpq(rcx, rbx);
+ __ cmpq(r8, rbx);
__ j(less, ©);
__ jmp(&invoke);
}
@@ -1391,23 +1422,23 @@
// Copy receiver and all actual arguments.
const int offset = StandardFrameConstants::kCallerSPOffset;
__ lea(rdi, Operand(rbp, rax, times_pointer_size, offset));
- __ Set(rcx, -1); // account for receiver
+ __ Set(r8, -1); // account for receiver
Label copy;
__ bind(©);
- __ incq(rcx);
+ __ incq(r8);
__ push(Operand(rdi, 0));
__ subq(rdi, Immediate(kPointerSize));
- __ cmpq(rcx, rax);
+ __ cmpq(r8, rax);
__ j(less, ©);
// Fill remaining expected arguments with undefined values.
Label fill;
__ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
__ bind(&fill);
- __ incq(rcx);
+ __ incq(r8);
__ push(kScratchRegister);
- __ cmpq(rcx, rbx);
+ __ cmpq(r8, rbx);
__ j(less, &fill);
// Restore function pointer.
@@ -1456,17 +1487,17 @@
// If the result was -1 it means that we couldn't optimize the
// function. Just return and continue in the unoptimized version.
- NearLabel skip;
+ Label skip;
__ SmiCompare(rax, Smi::FromInt(-1));
- __ j(not_equal, &skip);
+ __ j(not_equal, &skip, Label::kNear);
__ ret(0);
// If we decide not to perform on-stack replacement we perform a
// stack guard check to enable interrupts.
__ bind(&stack_check);
- NearLabel ok;
+ Label ok;
__ CompareRoot(rsp, Heap::kStackLimitRootIndex);
- __ j(above_equal, &ok);
+ __ j(above_equal, &ok, Label::kNear);
StackCheckStub stub;
__ TailCallStub(&stub);