Move (uppercase) JS builtins from js builtins object to native context.
R=bmeurer@chromium.org, mstarzinger@chromium.org, rmcilroy@chromium.org Review URL: https://codereview.chromium.org/1316943002 Cr-Commit-Position: refs/heads/master@{#30402}
This commit is contained in:
parent
7db48046ea
commit
b42c4459e6
@ -3373,8 +3373,7 @@ Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
|
||||
}
|
||||
PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Value::Equals()", bool);
|
||||
i::Handle<i::Object> args[] = { other };
|
||||
i::Handle<i::JSFunction> fun(i::JSFunction::cast(
|
||||
isolate->js_builtins_object()->javascript_builtin(i::Builtins::EQUALS)));
|
||||
i::Handle<i::JSFunction> fun = isolate->equals_builtin();
|
||||
i::Handle<i::Object> result;
|
||||
has_pending_exception =
|
||||
!i::Execution::Call(isolate, fun, self, arraysize(args), args)
|
||||
|
@ -236,7 +236,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
|
||||
{
|
||||
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
|
||||
__ push(r0);
|
||||
__ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_STRING_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
__ pop(function);
|
||||
__ mov(argument, r0);
|
||||
@ -768,7 +768,7 @@ static void Generate_CheckStackOverflow(MacroAssembler* masm,
|
||||
__ SmiTag(argc);
|
||||
}
|
||||
__ Push(r1, argc);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
|
||||
__ bind(&okay);
|
||||
}
|
||||
@ -920,7 +920,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
|
||||
__ cmp(r9, Operand(r2));
|
||||
__ b(hs, &ok);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
|
||||
// If ok, push undefined as the initial value for all register file entries.
|
||||
@ -1404,12 +1404,12 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
|
||||
__ push(r1); // re-add proxy object as additional argument
|
||||
__ add(r0, r0, Operand(1));
|
||||
__ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(r1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&non_proxy);
|
||||
__ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinFunction(r1, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ bind(&function);
|
||||
@ -1500,9 +1500,10 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array
|
||||
__ push(r0);
|
||||
if (targetIsArgument) {
|
||||
__ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged);
|
||||
@ -1594,7 +1595,7 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ push(r1); // add function proxy as last argument
|
||||
__ add(r0, r0, Operand(1));
|
||||
__ mov(r2, Operand::Zero());
|
||||
__ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(r1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
@ -1631,7 +1632,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
|
||||
__ push(r0);
|
||||
__ ldr(r0, MemOperand(fp, kNewTargetOffset)); // get the new.target
|
||||
__ push(r0);
|
||||
__ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged);
|
||||
|
||||
@ -1862,7 +1864,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bkpt(0);
|
||||
}
|
||||
}
|
||||
|
@ -682,12 +682,13 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
if (cc == eq && strict()) {
|
||||
__ TailCallRuntime(Runtime::kStrictEquals, 2, 1);
|
||||
} else {
|
||||
Builtins::JavaScript native;
|
||||
int context_index;
|
||||
if (cc == eq) {
|
||||
native = Builtins::EQUALS;
|
||||
context_index = Context::EQUALS_BUILTIN_INDEX;
|
||||
} else {
|
||||
native =
|
||||
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||
context_index = is_strong(strength())
|
||||
? Context::COMPARE_STRONG_BUILTIN_INDEX
|
||||
: Context::COMPARE_BUILTIN_INDEX;
|
||||
int ncr; // NaN compare result
|
||||
if (cc == lt || cc == le) {
|
||||
ncr = GREATER;
|
||||
@ -701,7 +702,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
|
||||
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
|
||||
// tagged as a small integer.
|
||||
__ InvokeBuiltin(native, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(context_index, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
__ bind(&miss);
|
||||
@ -2426,7 +2427,7 @@ static void EmitSlowCase(MacroAssembler* masm,
|
||||
__ push(r1); // put proxy as additional argument
|
||||
__ mov(r0, Operand(argc + 1, RelocInfo::NONE32));
|
||||
__ mov(r2, Operand::Zero());
|
||||
__ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(r1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
{
|
||||
Handle<Code> adaptor =
|
||||
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
|
||||
@ -2439,7 +2440,7 @@ static void EmitSlowCase(MacroAssembler* masm,
|
||||
__ str(r1, MemOperand(sp, argc * kPointerSize));
|
||||
__ mov(r0, Operand(argc)); // Set up the number of arguments.
|
||||
__ mov(r2, Operand::Zero());
|
||||
__ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinFunction(r1, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
@ -2576,11 +2577,13 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(&slow);
|
||||
__ cmp(r5, Operand(JS_FUNCTION_PROXY_TYPE));
|
||||
__ b(ne, &non_function_call);
|
||||
__ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinFunction(
|
||||
r1, Context::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ jmp(&do_call);
|
||||
|
||||
__ bind(&non_function_call);
|
||||
__ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinFunction(
|
||||
r1, Context::CALL_NON_FUNCTION_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ bind(&do_call);
|
||||
// Set expected number of arguments to zero (not changing r0).
|
||||
__ mov(r2, Operand::Zero());
|
||||
@ -3261,7 +3264,7 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(¬_oddball);
|
||||
|
||||
__ push(r0); // Push argument.
|
||||
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_NUMBER_BUILTIN_INDEX, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2507,13 +2507,12 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper) {
|
||||
// You can't call a builtin without a valid frame.
|
||||
DCHECK(flag == JUMP_FUNCTION || has_frame());
|
||||
|
||||
GetBuiltinEntry(r2, id);
|
||||
GetBuiltinEntry(r2, native_context_index);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
call_wrapper.BeforeCall(CallSize(r2));
|
||||
Call(r2);
|
||||
@ -2526,20 +2525,20 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinFunction(Register target,
|
||||
Builtins::JavaScript id) {
|
||||
int native_context_index) {
|
||||
// Load the builtins object into target register.
|
||||
ldr(target,
|
||||
MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
||||
ldr(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset));
|
||||
ldr(target, FieldMemOperand(target, GlobalObject::kNativeContextOffset));
|
||||
// Load the JavaScript builtin function from the builtins object.
|
||||
ldr(target, FieldMemOperand(target,
|
||||
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
|
||||
ldr(target, ContextOperand(target, native_context_index));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
|
||||
void MacroAssembler::GetBuiltinEntry(Register target,
|
||||
int native_context_index) {
|
||||
DCHECK(!target.is(r1));
|
||||
GetBuiltinFunction(r1, id);
|
||||
GetBuiltinFunction(r1, native_context_index);
|
||||
// Load the code entry point from the builtins object.
|
||||
ldr(target, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
|
||||
}
|
||||
|
@ -1151,18 +1151,16 @@ class MacroAssembler: public Assembler {
|
||||
// Jump to a runtime routine.
|
||||
void JumpToExternalReference(const ExternalReference& builtin);
|
||||
|
||||
// Invoke specified builtin JavaScript function. Adds an entry to
|
||||
// the unresolved list if the name does not resolve.
|
||||
void InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
// Invoke specified builtin JavaScript function.
|
||||
void InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper = NullCallWrapper());
|
||||
|
||||
// Store the code object for the given builtin in the target register and
|
||||
// setup the function in r1.
|
||||
void GetBuiltinEntry(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinEntry(Register target, int native_context_index);
|
||||
|
||||
// Store the function for the given builtin in the target register.
|
||||
void GetBuiltinFunction(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinFunction(Register target, int native_context_index);
|
||||
|
||||
Handle<Object> CodeObject() {
|
||||
DCHECK(!code_object_.is_null());
|
||||
|
@ -229,7 +229,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(arg);
|
||||
__ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_STRING_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
__ Pop(function);
|
||||
__ Mov(argument, x0);
|
||||
@ -780,7 +780,7 @@ static void Generate_CheckStackOverflow(MacroAssembler* masm,
|
||||
__ SmiTag(argc);
|
||||
}
|
||||
__ Push(function, argc);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
// We should never return from the APPLY_OVERFLOW builtin.
|
||||
if (__ emit_debug_code()) {
|
||||
__ Unreachable();
|
||||
@ -945,7 +945,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ Sub(x10, jssp, Operand(x11));
|
||||
__ CompareRoot(x10, Heap::kRealStackLimitRootIndex);
|
||||
__ B(hs, &ok);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ Bind(&ok);
|
||||
|
||||
// If ok, push undefined as the initial value for all register file entries.
|
||||
@ -1438,12 +1438,12 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
|
||||
__ Push(function); // Re-add proxy object as additional argument.
|
||||
__ Add(argc, argc, 1);
|
||||
__ GetBuiltinFunction(function, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(function, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ Bind(&non_proxy);
|
||||
__ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinFunction(function, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Bind(&js_function);
|
||||
@ -1542,9 +1542,10 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ Ldr(args, MemOperand(fp, kArgumentsOffset));
|
||||
__ Push(function, args);
|
||||
if (targetIsArgument) {
|
||||
__ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
Register argc = x0;
|
||||
|
||||
@ -1629,7 +1630,7 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ Push(function); // Add function proxy as last argument.
|
||||
__ Add(x0, x0, 1);
|
||||
__ Mov(x2, 0);
|
||||
__ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(x1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
@ -1673,7 +1674,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
|
||||
__ Ldr(args, MemOperand(fp, kArgumentsOffset));
|
||||
__ Ldr(newTarget, MemOperand(fp, kNewTargetOffset));
|
||||
__ Push(function, args, newTarget);
|
||||
__ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
Register argc = x0;
|
||||
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, argc, kArgcIsSmiTagged);
|
||||
@ -1926,7 +1928,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ Unreachable();
|
||||
}
|
||||
}
|
||||
|
@ -653,12 +653,13 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
if (cond == eq && strict()) {
|
||||
__ TailCallRuntime(Runtime::kStrictEquals, 2, 1);
|
||||
} else {
|
||||
Builtins::JavaScript native;
|
||||
int context_index;
|
||||
if (cond == eq) {
|
||||
native = Builtins::EQUALS;
|
||||
context_index = Context::EQUALS_BUILTIN_INDEX;
|
||||
} else {
|
||||
native =
|
||||
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||
context_index = is_strong(strength())
|
||||
? Context::COMPARE_STRONG_BUILTIN_INDEX
|
||||
: Context::COMPARE_BUILTIN_INDEX;
|
||||
int ncr; // NaN compare result
|
||||
if ((cond == lt) || (cond == le)) {
|
||||
ncr = GREATER;
|
||||
@ -672,7 +673,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
|
||||
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
|
||||
// tagged as a small integer.
|
||||
__ InvokeBuiltin(native, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(context_index, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
__ Bind(&miss);
|
||||
@ -2818,7 +2819,7 @@ static void EmitSlowCase(MacroAssembler* masm,
|
||||
__ Push(function); // put proxy as additional argument
|
||||
__ Mov(x0, argc + 1);
|
||||
__ Mov(x2, 0);
|
||||
__ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(x1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
{
|
||||
Handle<Code> adaptor =
|
||||
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
|
||||
@ -2831,7 +2832,7 @@ static void EmitSlowCase(MacroAssembler* masm,
|
||||
__ Poke(function, argc * kXRegSize);
|
||||
__ Mov(x0, argc); // Set up the number of arguments.
|
||||
__ Mov(x2, 0);
|
||||
__ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinFunction(function, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
@ -2979,11 +2980,13 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
__ Bind(&slow);
|
||||
__ Cmp(object_type, JS_FUNCTION_PROXY_TYPE);
|
||||
__ B(ne, &non_function_call);
|
||||
__ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinFunction(
|
||||
x1, Context::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ B(&do_call);
|
||||
|
||||
__ Bind(&non_function_call);
|
||||
__ GetBuiltinFunction(x1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinFunction(
|
||||
x1, Context::CALL_NON_FUNCTION_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
|
||||
__ Bind(&do_call);
|
||||
// Set expected number of arguments to zero (not changing x0).
|
||||
@ -3992,7 +3995,7 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
|
||||
__ Bind(¬_oddball);
|
||||
|
||||
__ Push(x0); // Push argument.
|
||||
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_NUMBER_BUILTIN_INDEX, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1687,35 +1687,32 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinFunction(Register target,
|
||||
Builtins::JavaScript id) {
|
||||
int native_context_index) {
|
||||
// Load the builtins object into target register.
|
||||
Ldr(target, GlobalObjectMemOperand());
|
||||
Ldr(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset));
|
||||
Ldr(target, FieldMemOperand(target, GlobalObject::kNativeContextOffset));
|
||||
// Load the JavaScript builtin function from the builtins object.
|
||||
Ldr(target, FieldMemOperand(target,
|
||||
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
|
||||
Ldr(target, ContextMemOperand(target, native_context_index));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinEntry(Register target,
|
||||
Register function,
|
||||
Builtins::JavaScript id) {
|
||||
void MacroAssembler::GetBuiltinEntry(Register target, Register function,
|
||||
int native_context_index) {
|
||||
DCHECK(!AreAliased(target, function));
|
||||
GetBuiltinFunction(function, id);
|
||||
GetBuiltinFunction(function, native_context_index);
|
||||
// Load the code entry point from the builtins object.
|
||||
Ldr(target, FieldMemOperand(function, JSFunction::kCodeEntryOffset));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper) {
|
||||
ASM_LOCATION("MacroAssembler::InvokeBuiltin");
|
||||
// You can't call a builtin without a valid frame.
|
||||
DCHECK(flag == JUMP_FUNCTION || has_frame());
|
||||
|
||||
// Get the builtin entry in x2 and setup the function object in x1.
|
||||
GetBuiltinEntry(x2, x1, id);
|
||||
GetBuiltinEntry(x2, x1, native_context_index);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
call_wrapper.BeforeCall(CallSize(x2));
|
||||
Call(x2);
|
||||
|
@ -1145,20 +1145,17 @@ class MacroAssembler : public Assembler {
|
||||
int num_arguments);
|
||||
|
||||
|
||||
// Invoke specified builtin JavaScript function. Adds an entry to
|
||||
// the unresolved list if the name does not resolve.
|
||||
void InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
// Invoke specified builtin JavaScript function.
|
||||
void InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper = NullCallWrapper());
|
||||
|
||||
// Store the code object for the given builtin in the target register and
|
||||
// setup the function in the function register.
|
||||
void GetBuiltinEntry(Register target,
|
||||
Register function,
|
||||
Builtins::JavaScript id);
|
||||
void GetBuiltinEntry(Register target, Register function,
|
||||
int native_context_index);
|
||||
|
||||
// Store the function for the given builtin in the target register.
|
||||
void GetBuiltinFunction(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinFunction(Register target, int native_context_index);
|
||||
|
||||
void Jump(Register target);
|
||||
void Jump(Address target, RelocInfo::Mode rmode);
|
||||
|
@ -1752,23 +1752,6 @@ void Genesis::InitializeBuiltinTypedArrays() {
|
||||
}
|
||||
|
||||
|
||||
bool Bootstrapper::InstallJSBuiltins(Isolate* isolate,
|
||||
Handle<JSObject> container) {
|
||||
HandleScope scope(isolate);
|
||||
Handle<JSBuiltinsObject> builtins = isolate->js_builtins_object();
|
||||
for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
|
||||
Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
|
||||
Handle<Object> function_object =
|
||||
Object::GetProperty(isolate, container, Builtins::GetName(id))
|
||||
.ToHandleChecked();
|
||||
DCHECK(function_object->IsJSFunction());
|
||||
Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
|
||||
builtins->set_javascript_builtin(id, *function);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Bootstrapper::ExportPrivateSymbols(Isolate* isolate,
|
||||
Handle<JSObject> container) {
|
||||
HandleScope scope(isolate);
|
||||
|
@ -119,7 +119,6 @@ class Bootstrapper final {
|
||||
static bool CompileCodeStubBuiltin(Isolate* isolate, int index);
|
||||
static bool InstallCodeStubNatives(Isolate* isolate);
|
||||
|
||||
static bool InstallJSBuiltins(Isolate* isolate, Handle<JSObject> container);
|
||||
static void ExportPrivateSymbols(Isolate* isolate,
|
||||
Handle<JSObject> container);
|
||||
|
||||
|
@ -1317,17 +1317,6 @@ Address const Builtins::c_functions_[cfunction_count] = {
|
||||
};
|
||||
#undef DEF_ENUM_C
|
||||
|
||||
#define DEF_JS_NAME(name, ignore) #name,
|
||||
#define DEF_JS_ARGC(ignore, argc) argc,
|
||||
const char* const Builtins::javascript_names_[id_count] = {
|
||||
BUILTINS_LIST_JS(DEF_JS_NAME)
|
||||
};
|
||||
|
||||
int const Builtins::javascript_argc_[id_count] = {
|
||||
BUILTINS_LIST_JS(DEF_JS_ARGC)
|
||||
};
|
||||
#undef DEF_JS_NAME
|
||||
#undef DEF_JS_ARGC
|
||||
|
||||
struct BuiltinDesc {
|
||||
byte* generator;
|
||||
|
@ -149,48 +149,6 @@ enum BuiltinExtraArguments {
|
||||
V(PlainReturn_LiveEdit, BUILTIN, DEBUG_STUB, kNoExtraICState) \
|
||||
V(FrameDropper_LiveEdit, BUILTIN, DEBUG_STUB, kNoExtraICState)
|
||||
|
||||
// Define list of builtins implemented in JavaScript.
|
||||
#define BUILTINS_LIST_JS(V) \
|
||||
V(EQUALS, 1) \
|
||||
V(COMPARE, 2) \
|
||||
V(COMPARE_STRONG, 2) \
|
||||
V(ADD, 1) \
|
||||
V(ADD_STRONG, 1) \
|
||||
V(SUB, 1) \
|
||||
V(SUB_STRONG, 1) \
|
||||
V(MUL, 1) \
|
||||
V(MUL_STRONG, 1) \
|
||||
V(DIV, 1) \
|
||||
V(DIV_STRONG, 1) \
|
||||
V(MOD, 1) \
|
||||
V(MOD_STRONG, 1) \
|
||||
V(BIT_OR, 1) \
|
||||
V(BIT_OR_STRONG, 1) \
|
||||
V(BIT_AND, 1) \
|
||||
V(BIT_AND_STRONG, 1) \
|
||||
V(BIT_XOR, 1) \
|
||||
V(BIT_XOR_STRONG, 1) \
|
||||
V(SHL, 1) \
|
||||
V(SHL_STRONG, 1) \
|
||||
V(SAR, 1) \
|
||||
V(SAR_STRONG, 1) \
|
||||
V(SHR, 1) \
|
||||
V(SHR_STRONG, 1) \
|
||||
V(IN, 1) \
|
||||
V(CALL_NON_FUNCTION, 0) \
|
||||
V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \
|
||||
V(CALL_FUNCTION_PROXY, 1) \
|
||||
V(CALL_FUNCTION_PROXY_AS_CONSTRUCTOR, 1) \
|
||||
V(TO_NUMBER, 0) \
|
||||
V(TO_STRING, 0) \
|
||||
V(TO_NAME, 0) \
|
||||
V(STRING_ADD_LEFT, 1) \
|
||||
V(STRING_ADD_RIGHT, 1) \
|
||||
V(APPLY_PREPARE, 1) \
|
||||
V(REFLECT_APPLY_PREPARE, 1) \
|
||||
V(REFLECT_CONSTRUCT_PREPARE, 2) \
|
||||
V(CONCAT_ITERABLE_TO_ARRAY, 1) \
|
||||
V(STACK_OVERFLOW, 1)
|
||||
|
||||
class BuiltinFunctionTable;
|
||||
class ObjectVisitor;
|
||||
@ -231,13 +189,6 @@ class Builtins {
|
||||
cfunction_count
|
||||
};
|
||||
|
||||
enum JavaScript {
|
||||
#define DEF_ENUM(name, ignore) name,
|
||||
BUILTINS_LIST_JS(DEF_ENUM)
|
||||
#undef DEF_ENUM
|
||||
id_count
|
||||
};
|
||||
|
||||
#define DECLARE_BUILTIN_ACCESSOR_C(name, ignore) Handle<Code> name();
|
||||
#define DECLARE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
|
||||
Handle<Code> name();
|
||||
@ -263,14 +214,11 @@ class Builtins {
|
||||
return c_functions_[id];
|
||||
}
|
||||
|
||||
static const char* GetName(JavaScript id) { return javascript_names_[id]; }
|
||||
const char* name(int index) {
|
||||
DCHECK(index >= 0);
|
||||
DCHECK(index < builtin_count);
|
||||
return names_[index];
|
||||
}
|
||||
static int GetArgumentsCount(JavaScript id) { return javascript_argc_[id]; }
|
||||
static int NumberOfJavaScriptBuiltins() { return id_count; }
|
||||
|
||||
bool is_initialized() const { return initialized_; }
|
||||
|
||||
@ -289,8 +237,6 @@ class Builtins {
|
||||
// function f, we use an Object* array here.
|
||||
Object* builtins_[builtin_count];
|
||||
const char* names_[builtin_count];
|
||||
static const char* const javascript_names_[id_count];
|
||||
static int const javascript_argc_[id_count];
|
||||
|
||||
static void Generate_Adaptor(MacroAssembler* masm,
|
||||
CFunctionId id,
|
||||
|
@ -1985,10 +1985,8 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
if (subexpr->IsSpread()) {
|
||||
VisitForValue(subexpr->AsSpread()->expression());
|
||||
Node* iterable = environment()->Pop();
|
||||
Node* builtins = BuildLoadBuiltinsObject();
|
||||
Node* function = BuildLoadObjectField(
|
||||
builtins, JSBuiltinsObject::OffsetOfFunctionWithId(
|
||||
Builtins::CONCAT_ITERABLE_TO_ARRAY));
|
||||
Node* function = BuildLoadNativeContextField(
|
||||
Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX);
|
||||
result = NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS,
|
||||
language_mode()),
|
||||
function, array, iterable);
|
||||
@ -2541,12 +2539,7 @@ void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
|
||||
// The callee and the receiver both have to be pushed onto the operand stack
|
||||
// before arguments are being evaluated.
|
||||
CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
|
||||
Node* global = BuildLoadGlobalObject();
|
||||
Node* native_context =
|
||||
BuildLoadObjectField(global, GlobalObject::kNativeContextOffset);
|
||||
Node* callee_value =
|
||||
NewNode(javascript()->LoadContext(0, expr->context_index(), true),
|
||||
native_context);
|
||||
Node* callee_value = BuildLoadNativeContextField(expr->context_index());
|
||||
Node* receiver_value = jsgraph()->UndefinedConstant();
|
||||
|
||||
environment()->Push(callee_value);
|
||||
@ -3759,6 +3752,14 @@ Node* AstGraphBuilder::BuildLoadGlobalObject() {
|
||||
}
|
||||
|
||||
|
||||
Node* AstGraphBuilder::BuildLoadNativeContextField(int index) {
|
||||
Node* global = BuildLoadGlobalObject();
|
||||
Node* native_context =
|
||||
BuildLoadObjectField(global, GlobalObject::kNativeContextOffset);
|
||||
return NewNode(javascript()->LoadContext(0, index, true), native_context);
|
||||
}
|
||||
|
||||
|
||||
Node* AstGraphBuilder::BuildLoadGlobalProxy() {
|
||||
Node* global = BuildLoadGlobalObject();
|
||||
Node* proxy =
|
||||
|
@ -317,6 +317,7 @@ class AstGraphBuilder : public AstVisitor {
|
||||
// Builders for accessing the function context.
|
||||
Node* BuildLoadBuiltinsObject();
|
||||
Node* BuildLoadGlobalObject();
|
||||
Node* BuildLoadNativeContextField(int index);
|
||||
Node* BuildLoadGlobalProxy();
|
||||
Node* BuildLoadFeedbackVector();
|
||||
|
||||
|
@ -195,20 +195,23 @@ Node* InterpreterAssembler::LoadObjectField(Node* object, int offset) {
|
||||
}
|
||||
|
||||
|
||||
Node* InterpreterAssembler::LoadContextSlot(int slot_index) {
|
||||
return raw_assembler_->Load(kMachAnyTagged, ContextTaggedPointer(),
|
||||
Node* InterpreterAssembler::LoadContextSlot(Node* context, int slot_index) {
|
||||
return raw_assembler_->Load(kMachAnyTagged, context,
|
||||
IntPtrConstant(Context::SlotOffset(slot_index)));
|
||||
}
|
||||
|
||||
|
||||
Node* InterpreterAssembler::CallJSBuiltin(Builtins::JavaScript builtin,
|
||||
Node* receiver, Node** js_args,
|
||||
int js_arg_count) {
|
||||
Node* InterpreterAssembler::LoadContextSlot(int slot_index) {
|
||||
return LoadContextSlot(ContextTaggedPointer(), slot_index);
|
||||
}
|
||||
|
||||
|
||||
Node* InterpreterAssembler::CallJSBuiltin(int context_index, Node* receiver,
|
||||
Node** js_args, int js_arg_count) {
|
||||
Node* global_object = LoadContextSlot(Context::GLOBAL_OBJECT_INDEX);
|
||||
Node* builtins_object =
|
||||
LoadObjectField(global_object, GlobalObject::kBuiltinsOffset);
|
||||
Node* function = LoadObjectField(
|
||||
builtins_object, JSBuiltinsObject::OffsetOfFunctionWithId(builtin));
|
||||
Node* native_context =
|
||||
LoadObjectField(global_object, GlobalObject::kNativeContextOffset);
|
||||
Node* function = LoadContextSlot(native_context, context_index);
|
||||
Node* context = LoadObjectField(function, JSFunction::kContextOffset);
|
||||
|
||||
int index = 0;
|
||||
@ -225,15 +228,14 @@ Node* InterpreterAssembler::CallJSBuiltin(Builtins::JavaScript builtin,
|
||||
}
|
||||
|
||||
|
||||
Node* InterpreterAssembler::CallJSBuiltin(Builtins::JavaScript builtin,
|
||||
Node* receiver) {
|
||||
return CallJSBuiltin(builtin, receiver, nullptr, 0);
|
||||
Node* InterpreterAssembler::CallJSBuiltin(int context_index, Node* receiver) {
|
||||
return CallJSBuiltin(context_index, receiver, nullptr, 0);
|
||||
}
|
||||
|
||||
|
||||
Node* InterpreterAssembler::CallJSBuiltin(Builtins::JavaScript builtin,
|
||||
Node* receiver, Node* arg1) {
|
||||
return CallJSBuiltin(builtin, receiver, &arg1, 1);
|
||||
Node* InterpreterAssembler::CallJSBuiltin(int context_index, Node* receiver,
|
||||
Node* arg1) {
|
||||
return CallJSBuiltin(context_index, receiver, &arg1, 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,12 +65,15 @@ class InterpreterAssembler {
|
||||
// Load a field from an object on the heap.
|
||||
Node* LoadObjectField(Node* object, int offset);
|
||||
|
||||
// Load |slot_index| from a context.
|
||||
Node* LoadContextSlot(Node* context, int slot_index);
|
||||
|
||||
// Load |slot_index| from the current context.
|
||||
Node* LoadContextSlot(int slot_index);
|
||||
|
||||
// Call JS builtin.
|
||||
Node* CallJSBuiltin(Builtins::JavaScript builtin, Node* receiver);
|
||||
Node* CallJSBuiltin(Builtins::JavaScript builtin, Node* receiver, Node* arg1);
|
||||
Node* CallJSBuiltin(int context_index, Node* receiver);
|
||||
Node* CallJSBuiltin(int context_index, Node* receiver, Node* arg1);
|
||||
|
||||
// Returns from the function.
|
||||
void Return();
|
||||
@ -105,8 +108,8 @@ class InterpreterAssembler {
|
||||
Node* BytecodeOperand(int operand_index);
|
||||
Node* BytecodeOperandSignExtended(int operand_index);
|
||||
|
||||
Node* CallJSBuiltin(Builtins::JavaScript builtin, Node* receiver,
|
||||
Node** js_args, int js_arg_count);
|
||||
Node* CallJSBuiltin(int context_index, Node* receiver, Node** js_args,
|
||||
int js_arg_count);
|
||||
|
||||
// Returns BytecodeOffset() advanced by delta bytecodes. Note: this does not
|
||||
// update BytecodeOffset() itself.
|
||||
|
@ -214,8 +214,7 @@ void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
|
||||
}
|
||||
|
||||
|
||||
void JSGenericLowering::ReplaceWithBuiltinCall(Node* node,
|
||||
Builtins::JavaScript id,
|
||||
void JSGenericLowering::ReplaceWithBuiltinCall(Node* node, int context_index,
|
||||
int nargs) {
|
||||
Node* context_input = NodeProperties::GetContextInput(node);
|
||||
Node* effect_input = NodeProperties::GetEffectInput(node);
|
||||
@ -231,14 +230,14 @@ void JSGenericLowering::ReplaceWithBuiltinCall(Node* node,
|
||||
jsgraph()->IntPtrConstant(
|
||||
Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)),
|
||||
effect_input, graph()->start());
|
||||
Node* builtins_object = graph()->NewNode(
|
||||
machine()->Load(kMachAnyTagged), global_object,
|
||||
jsgraph()->IntPtrConstant(GlobalObject::kBuiltinsOffset - kHeapObjectTag),
|
||||
effect_input, graph()->start());
|
||||
Node* native_context =
|
||||
graph()->NewNode(machine()->Load(kMachAnyTagged), global_object,
|
||||
jsgraph()->IntPtrConstant(
|
||||
GlobalObject::kNativeContextOffset - kHeapObjectTag),
|
||||
effect_input, graph()->start());
|
||||
Node* function = graph()->NewNode(
|
||||
machine()->Load(kMachAnyTagged), builtins_object,
|
||||
jsgraph()->IntPtrConstant(JSBuiltinsObject::OffsetOfFunctionWithId(id) -
|
||||
kHeapObjectTag),
|
||||
machine()->Load(kMachAnyTagged), native_context,
|
||||
jsgraph()->IntPtrConstant(Context::SlotOffset(context_index)),
|
||||
effect_input, graph()->start());
|
||||
Node* stub_code = jsgraph()->HeapConstant(callable.code());
|
||||
node->InsertInput(zone(), 0, stub_code);
|
||||
@ -297,12 +296,12 @@ void JSGenericLowering::LowerJSToNumber(Node* node) {
|
||||
|
||||
|
||||
void JSGenericLowering::LowerJSToString(Node* node) {
|
||||
ReplaceWithBuiltinCall(node, Builtins::TO_STRING, 1);
|
||||
ReplaceWithBuiltinCall(node, Context::TO_STRING_BUILTIN_INDEX, 1);
|
||||
}
|
||||
|
||||
|
||||
void JSGenericLowering::LowerJSToName(Node* node) {
|
||||
ReplaceWithBuiltinCall(node, Builtins::TO_NAME, 1);
|
||||
ReplaceWithBuiltinCall(node, Context::TO_NAME_BUILTIN_INDEX, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -437,7 +436,7 @@ void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
|
||||
|
||||
|
||||
void JSGenericLowering::LowerJSHasProperty(Node* node) {
|
||||
ReplaceWithBuiltinCall(node, Builtins::IN, 2);
|
||||
ReplaceWithBuiltinCall(node, Context::IN_BUILTIN_INDEX, 2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ class JSGenericLowering final : public Reducer {
|
||||
// Helpers to replace existing nodes with a generic call.
|
||||
void ReplaceWithCompareIC(Node* node, Token::Value token);
|
||||
void ReplaceWithStubCall(Node* node, Callable c, CallDescriptor::Flags flags);
|
||||
void ReplaceWithBuiltinCall(Node* node, Builtins::JavaScript id, int args);
|
||||
void ReplaceWithBuiltinCall(Node* node, int context_index, int args);
|
||||
void ReplaceWithRuntimeCall(Node* node, Runtime::FunctionId f, int args = -1);
|
||||
|
||||
Zone* zone() const;
|
||||
|
@ -990,10 +990,8 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
// TODO(mstarzinger): This is just a temporary hack to make TurboFan work,
|
||||
// the correct solution is to restore the context register after invoking
|
||||
// builtins from full-codegen.
|
||||
for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
|
||||
Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
|
||||
Object* builtin = isolate()->js_builtins_object()->javascript_builtin(id);
|
||||
if (*info()->closure() == builtin) return Handle<Code>::null();
|
||||
if (Context::IsJSBuiltin(isolate()->native_context(), info()->closure())) {
|
||||
return Handle<Code>::null();
|
||||
}
|
||||
|
||||
ZonePool zone_pool;
|
||||
|
@ -554,6 +554,16 @@ int Context::IntrinsicIndexForName(Handle<String> string) {
|
||||
#undef COMPARE_NAME
|
||||
|
||||
|
||||
bool Context::IsJSBuiltin(Handle<Context> native_context,
|
||||
Handle<JSFunction> function) {
|
||||
#define COMPARE_FUNCTION(index, type, name) \
|
||||
if (*function == native_context->get(index)) return true;
|
||||
NATIVE_CONTEXT_JS_BUILTINS(COMPARE_FUNCTION);
|
||||
#undef COMPARE_FUNCTION
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
bool Context::IsBootstrappingOrValidParentContext(
|
||||
Object* object, Context* child) {
|
||||
|
@ -90,6 +90,56 @@ enum BindingFlags {
|
||||
V(TO_PRIMITIVE_INDEX, JSFunction, to_primitive) \
|
||||
V(TO_STRING_FUN_INDEX, JSFunction, to_string_fun)
|
||||
|
||||
|
||||
#define NATIVE_CONTEXT_JS_BUILTINS(V) \
|
||||
V(ADD_BUILTIN_INDEX, JSFunction, add_builtin) \
|
||||
V(ADD_STRONG_BUILTIN_INDEX, JSFunction, add_strong_builtin) \
|
||||
V(APPLY_PREPARE_BUILTIN_INDEX, JSFunction, apply_prepare_builtin) \
|
||||
V(BIT_AND_BUILTIN_INDEX, JSFunction, bit_and_builtin) \
|
||||
V(BIT_AND_STRONG_BUILTIN_INDEX, JSFunction, bit_and_strong_builtin) \
|
||||
V(BIT_OR_BUILTIN_INDEX, JSFunction, bit_or_builtin) \
|
||||
V(BIT_OR_STRONG_BUILTIN_INDEX, JSFunction, bit_or_strong_builtin) \
|
||||
V(BIT_XOR_BUILTIN_INDEX, JSFunction, bit_xor_builtin) \
|
||||
V(BIT_XOR_STRONG_BUILTIN_INDEX, JSFunction, bit_xor_strong_builtin) \
|
||||
V(CALL_FUNCTION_PROXY_AS_CONSTRUCTOR_BUILTIN_INDEX, JSFunction, \
|
||||
call_function_proxy_as_constructor_builtin) \
|
||||
V(CALL_FUNCTION_PROXY_BUILTIN_INDEX, JSFunction, \
|
||||
call_function_proxy_builtin) \
|
||||
V(CALL_NON_FUNCTION_AS_CONSTRUCTOR_BUILTIN_INDEX, JSFunction, \
|
||||
call_non_function_as_constructor_builtin) \
|
||||
V(CALL_NON_FUNCTION_BUILTIN_INDEX, JSFunction, call_non_function_builtin) \
|
||||
V(COMPARE_BUILTIN_INDEX, JSFunction, compare_builtin) \
|
||||
V(COMPARE_STRONG_BUILTIN_INDEX, JSFunction, compare_strong_builtin) \
|
||||
V(CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX, JSFunction, \
|
||||
concat_iterable_to_array_builtin) \
|
||||
V(DIV_BUILTIN_INDEX, JSFunction, div_builtin) \
|
||||
V(DIV_STRONG_BUILTIN_INDEX, JSFunction, div_strong_builtin) \
|
||||
V(EQUALS_BUILTIN_INDEX, JSFunction, equals_builtin) \
|
||||
V(IN_BUILTIN_INDEX, JSFunction, in_builtin) \
|
||||
V(MOD_BUILTIN_INDEX, JSFunction, mod_builtin) \
|
||||
V(MOD_STRONG_BUILTIN_INDEX, JSFunction, mod_strong_builtin) \
|
||||
V(MUL_BUILTIN_INDEX, JSFunction, mul_builtin) \
|
||||
V(MUL_STRONG_BUILTIN_INDEX, JSFunction, mul_strong_builtin) \
|
||||
V(REFLECT_APPLY_PREPARE_BUILTIN_INDEX, JSFunction, \
|
||||
reflect_apply_prepare_builtin) \
|
||||
V(REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, JSFunction, \
|
||||
reflect_construct_prepare_builtin) \
|
||||
V(SAR_BUILTIN_INDEX, JSFunction, sar_builtin) \
|
||||
V(SAR_STRONG_BUILTIN_INDEX, JSFunction, sar_strong_builtin) \
|
||||
V(SHL_BUILTIN_INDEX, JSFunction, shl_builtin) \
|
||||
V(SHL_STRONG_BUILTIN_INDEX, JSFunction, shl_strong_builtin) \
|
||||
V(SHR_BUILTIN_INDEX, JSFunction, shr_builtin) \
|
||||
V(SHR_STRONG_BUILTIN_INDEX, JSFunction, shr_strong_builtin) \
|
||||
V(STACK_OVERFLOW_BUILTIN_INDEX, JSFunction, stack_overflow_builtin) \
|
||||
V(STRING_ADD_LEFT_BUILTIN_INDEX, JSFunction, string_add_left_builtin) \
|
||||
V(STRING_ADD_RIGHT_BUILTIN_INDEX, JSFunction, string_add_right_builtin) \
|
||||
V(SUB_BUILTIN_INDEX, JSFunction, sub_builtin) \
|
||||
V(SUB_STRONG_BUILTIN_INDEX, JSFunction, sub_strong_builtin) \
|
||||
V(TO_NAME_BUILTIN_INDEX, JSFunction, to_name_builtin) \
|
||||
V(TO_NUMBER_BUILTIN_INDEX, JSFunction, to_number_builtin) \
|
||||
V(TO_STRING_BUILTIN_INDEX, JSFunction, to_string_builtin)
|
||||
|
||||
|
||||
#define NATIVE_CONTEXT_IMPORTED_FIELDS(V) \
|
||||
V(ARRAY_CONCAT_INDEX, JSFunction, array_concat) \
|
||||
V(ARRAY_POP_INDEX, JSFunction, array_pop) \
|
||||
@ -152,7 +202,8 @@ enum BindingFlags {
|
||||
V(TO_DETAIL_STRING_FUN_INDEX, JSFunction, to_detail_string_fun) \
|
||||
V(TO_INTEGER_FUN_INDEX, JSFunction, to_integer_fun) \
|
||||
V(TYPE_ERROR_FUNCTION_INDEX, JSFunction, type_error_function) \
|
||||
V(URI_ERROR_FUNCTION_INDEX, JSFunction, uri_error_function)
|
||||
V(URI_ERROR_FUNCTION_INDEX, JSFunction, uri_error_function) \
|
||||
NATIVE_CONTEXT_JS_BUILTINS(V)
|
||||
|
||||
#define NATIVE_CONTEXT_FIELDS(V) \
|
||||
V(GLOBAL_PROXY_INDEX, JSObject, global_proxy_object) \
|
||||
@ -498,6 +549,9 @@ class Context: public FixedArray {
|
||||
static int ImportedFieldIndexForName(Handle<String> name);
|
||||
static int IntrinsicIndexForName(Handle<String> name);
|
||||
|
||||
static bool IsJSBuiltin(Handle<Context> native_context,
|
||||
Handle<JSFunction> function);
|
||||
|
||||
#define NATIVE_CONTEXT_FIELD_ACCESSORS(index, type, name) \
|
||||
void set_##name(type* value) { \
|
||||
DCHECK(IsNativeContext()); \
|
||||
|
@ -156,7 +156,7 @@ void FullCodeGenerator::Generate() {
|
||||
__ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
|
||||
__ cmp(r9, Operand(r2));
|
||||
__ b(hs, &ok);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
}
|
||||
__ LoadRoot(r9, Heap::kUndefinedValueRootIndex);
|
||||
@ -1908,7 +1908,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ Push(r0);
|
||||
if (subexpr->IsSpread()) {
|
||||
VisitForStackValue(subexpr->AsSpread()->expression());
|
||||
__ InvokeBuiltin(Builtins::CONCAT_ITERABLE_TO_ARRAY, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
VisitForStackValue(subexpr);
|
||||
__ CallRuntime(Runtime::kAppendElement, 2);
|
||||
@ -5049,7 +5050,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
switch (op) {
|
||||
case Token::IN:
|
||||
VisitForStackValue(expr->right());
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ CompareRoot(r0, Heap::kTrueValueRootIndex);
|
||||
Split(eq, if_true, if_false, fall_through);
|
||||
|
@ -160,7 +160,7 @@ void FullCodeGenerator::Generate() {
|
||||
__ Sub(x10, jssp, locals_count * kPointerSize);
|
||||
__ CompareRoot(x10, Heap::kRealStackLimitRootIndex);
|
||||
__ B(hs, &ok);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ Bind(&ok);
|
||||
}
|
||||
__ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
|
||||
@ -1889,7 +1889,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ Push(x0);
|
||||
if (subexpr->IsSpread()) {
|
||||
VisitForStackValue(subexpr->AsSpread()->expression());
|
||||
__ InvokeBuiltin(Builtins::CONCAT_ITERABLE_TO_ARRAY, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
VisitForStackValue(subexpr);
|
||||
__ CallRuntime(Runtime::kAppendElement, 2);
|
||||
@ -4756,7 +4757,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
switch (op) {
|
||||
case Token::IN:
|
||||
VisitForStackValue(expr->right());
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ CompareRoot(x0, Heap::kTrueValueRootIndex);
|
||||
Split(eq, if_true, if_false, fall_through);
|
||||
|
@ -883,7 +883,7 @@ void FullCodeGenerator::EmitUnwindBeforeReturn() {
|
||||
void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property,
|
||||
BailoutId bailout_id) {
|
||||
VisitForStackValue(property->key());
|
||||
__ InvokeBuiltin(Builtins::TO_NAME, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_NAME_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
PrepareForBailoutForId(bailout_id, NO_REGISTERS);
|
||||
__ Push(result_register());
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ void FullCodeGenerator::Generate() {
|
||||
ExternalReference::address_of_real_stack_limit(isolate());
|
||||
__ cmp(ecx, Operand::StaticVariable(stack_limit));
|
||||
__ j(above_equal, &ok, Label::kNear);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
}
|
||||
__ mov(eax, Immediate(isolate()->factory()->undefined_value()));
|
||||
@ -1841,7 +1841,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ Push(eax);
|
||||
if (subexpr->IsSpread()) {
|
||||
VisitForStackValue(subexpr->AsSpread()->expression());
|
||||
__ InvokeBuiltin(Builtins::CONCAT_ITERABLE_TO_ARRAY, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
VisitForStackValue(subexpr);
|
||||
__ CallRuntime(Runtime::kAppendElement, 2);
|
||||
@ -4989,7 +4990,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
switch (op) {
|
||||
case Token::IN:
|
||||
VisitForStackValue(expr->right());
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ cmp(eax, isolate()->factory()->true_value());
|
||||
Split(equal, if_true, if_false, fall_through);
|
||||
|
@ -163,7 +163,7 @@ void FullCodeGenerator::Generate() {
|
||||
__ Subu(t5, sp, Operand(locals_count * kPointerSize));
|
||||
__ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
|
||||
__ Branch(&ok, hs, t5, Operand(a2));
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
}
|
||||
__ LoadRoot(t5, Heap::kUndefinedValueRootIndex);
|
||||
@ -1907,7 +1907,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ Push(v0);
|
||||
if (subexpr->IsSpread()) {
|
||||
VisitForStackValue(subexpr->AsSpread()->expression());
|
||||
__ InvokeBuiltin(Builtins::CONCAT_ITERABLE_TO_ARRAY, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
VisitForStackValue(subexpr);
|
||||
__ CallRuntime(Runtime::kAppendElement, 2);
|
||||
@ -5076,7 +5077,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
switch (op) {
|
||||
case Token::IN:
|
||||
VisitForStackValue(expr->right());
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ LoadRoot(t0, Heap::kTrueValueRootIndex);
|
||||
Split(eq, v0, Operand(t0), if_true, if_false, fall_through);
|
||||
|
@ -160,7 +160,7 @@ void FullCodeGenerator::Generate() {
|
||||
__ Dsubu(t1, sp, Operand(locals_count * kPointerSize));
|
||||
__ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
|
||||
__ Branch(&ok, hs, t1, Operand(a2));
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
}
|
||||
__ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
|
||||
@ -1904,7 +1904,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ Push(v0);
|
||||
if (subexpr->IsSpread()) {
|
||||
VisitForStackValue(subexpr->AsSpread()->expression());
|
||||
__ InvokeBuiltin(Builtins::CONCAT_ITERABLE_TO_ARRAY, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
VisitForStackValue(subexpr);
|
||||
__ CallRuntime(Runtime::kAppendElement, 2);
|
||||
@ -5078,7 +5079,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
switch (op) {
|
||||
case Token::IN:
|
||||
VisitForStackValue(expr->right());
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ LoadRoot(a4, Heap::kTrueValueRootIndex);
|
||||
Split(eq, v0, Operand(a4), if_true, if_false, fall_through);
|
||||
|
@ -161,7 +161,7 @@ void FullCodeGenerator::Generate() {
|
||||
__ LoadRoot(r5, Heap::kRealStackLimitRootIndex);
|
||||
__ cmpl(ip, r5);
|
||||
__ bc_short(ge, &ok);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
}
|
||||
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
|
||||
@ -1868,7 +1868,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ Push(r3);
|
||||
if (subexpr->IsSpread()) {
|
||||
VisitForStackValue(subexpr->AsSpread()->expression());
|
||||
__ InvokeBuiltin(Builtins::CONCAT_ITERABLE_TO_ARRAY, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
VisitForStackValue(subexpr);
|
||||
__ CallRuntime(Runtime::kAppendElement, 2);
|
||||
@ -5067,7 +5068,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
switch (op) {
|
||||
case Token::IN:
|
||||
VisitForStackValue(expr->right());
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ LoadRoot(ip, Heap::kTrueValueRootIndex);
|
||||
__ cmp(r3, ip);
|
||||
|
@ -148,7 +148,7 @@ void FullCodeGenerator::Generate() {
|
||||
__ subp(rcx, Immediate(locals_count * kPointerSize));
|
||||
__ CompareRoot(rcx, Heap::kRealStackLimitRootIndex);
|
||||
__ j(above_equal, &ok, Label::kNear);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
}
|
||||
__ LoadRoot(rdx, Heap::kUndefinedValueRootIndex);
|
||||
@ -1866,7 +1866,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ Push(rax);
|
||||
if (subexpr->IsSpread()) {
|
||||
VisitForStackValue(subexpr->AsSpread()->expression());
|
||||
__ InvokeBuiltin(Builtins::CONCAT_ITERABLE_TO_ARRAY, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
VisitForStackValue(subexpr);
|
||||
__ CallRuntime(Runtime::kAppendElement, 2);
|
||||
@ -4998,7 +4999,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
switch (op) {
|
||||
case Token::IN:
|
||||
VisitForStackValue(expr->right());
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ CompareRoot(rax, Heap::kTrueValueRootIndex);
|
||||
Split(equal, if_true, if_false, fall_through);
|
||||
|
@ -151,7 +151,7 @@ void FullCodeGenerator::Generate() {
|
||||
ExternalReference::address_of_real_stack_limit(isolate());
|
||||
__ cmp(ecx, Operand::StaticVariable(stack_limit));
|
||||
__ j(above_equal, &ok, Label::kNear);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
}
|
||||
__ mov(eax, Immediate(isolate()->factory()->undefined_value()));
|
||||
@ -1832,7 +1832,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ Push(eax);
|
||||
if (subexpr->IsSpread()) {
|
||||
VisitForStackValue(subexpr->AsSpread()->expression());
|
||||
__ InvokeBuiltin(Builtins::CONCAT_ITERABLE_TO_ARRAY, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
VisitForStackValue(subexpr);
|
||||
__ CallRuntime(Runtime::kAppendElement, 2);
|
||||
@ -4980,7 +4981,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
switch (op) {
|
||||
case Token::IN:
|
||||
VisitForStackValue(expr->right());
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::IN_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ cmp(eax, isolate()->factory()->true_value());
|
||||
Split(equal, if_true, if_false, fall_through);
|
||||
|
@ -3508,16 +3508,15 @@ HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray(
|
||||
}
|
||||
|
||||
|
||||
HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) {
|
||||
HValue* HGraphBuilder::AddLoadJSBuiltin(int context_index) {
|
||||
HValue* global_object = Add<HLoadNamedField>(
|
||||
context(), nullptr,
|
||||
HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
|
||||
HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(
|
||||
GlobalObject::kBuiltinsOffset);
|
||||
HValue* builtins = Add<HLoadNamedField>(global_object, nullptr, access);
|
||||
HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset(
|
||||
JSBuiltinsObject::OffsetOfFunctionWithId(builtin));
|
||||
return Add<HLoadNamedField>(builtins, nullptr, function_access);
|
||||
GlobalObject::kNativeContextOffset);
|
||||
HValue* native_context = Add<HLoadNamedField>(global_object, nullptr, access);
|
||||
HObjectAccess function_access = HObjectAccess::ForContextSlot(context_index);
|
||||
return Add<HLoadNamedField>(native_context, nullptr, function_access);
|
||||
}
|
||||
|
||||
|
||||
@ -10911,7 +10910,8 @@ HValue* HGraphBuilder::BuildBinaryOperation(
|
||||
left = BuildNumberToString(left, left_type);
|
||||
} else if (!left_type->Is(Type::String())) {
|
||||
DCHECK(right_type->Is(Type::String()));
|
||||
HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT);
|
||||
HValue* function =
|
||||
AddLoadJSBuiltin(Context::STRING_ADD_RIGHT_BUILTIN_INDEX);
|
||||
Add<HPushArguments>(left, right);
|
||||
return AddUncasted<HInvokeFunction>(function, 2);
|
||||
}
|
||||
@ -10922,7 +10922,8 @@ HValue* HGraphBuilder::BuildBinaryOperation(
|
||||
right = BuildNumberToString(right, right_type);
|
||||
} else if (!right_type->Is(Type::String())) {
|
||||
DCHECK(left_type->Is(Type::String()));
|
||||
HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT);
|
||||
HValue* function =
|
||||
AddLoadJSBuiltin(Context::STRING_ADD_LEFT_BUILTIN_INDEX);
|
||||
Add<HPushArguments>(left, right);
|
||||
return AddUncasted<HInvokeFunction>(function, 2);
|
||||
}
|
||||
@ -10990,7 +10991,7 @@ HValue* HGraphBuilder::BuildBinaryOperation(
|
||||
// operation in optimized code, which is more expensive, than a stub call.
|
||||
if (graph()->info()->IsStub() && is_non_primitive) {
|
||||
HValue* function =
|
||||
AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op, strength));
|
||||
AddLoadJSBuiltin(BinaryOpIC::TokenToContextIndex(op, strength));
|
||||
Add<HPushArguments>(left, right);
|
||||
instr = AddUncasted<HInvokeFunction>(function, 2);
|
||||
} else {
|
||||
@ -11352,7 +11353,7 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
|
||||
return ast_context()->ReturnInstruction(result, expr->id());
|
||||
|
||||
} else if (op == Token::IN) {
|
||||
HValue* function = AddLoadJSBuiltin(Builtins::IN);
|
||||
HValue* function = AddLoadJSBuiltin(Context::IN_BUILTIN_INDEX);
|
||||
Add<HPushArguments>(left, right);
|
||||
// TODO(olivf) InvokeFunction produces a check for the parameter count,
|
||||
// even though we are certain to pass the correct number of arguments here.
|
||||
|
@ -1443,7 +1443,7 @@ class HGraphBuilder {
|
||||
ElementsKind kind,
|
||||
HValue *dependency = NULL);
|
||||
|
||||
HValue* AddLoadJSBuiltin(Builtins::JavaScript builtin);
|
||||
HValue* AddLoadJSBuiltin(int context_index);
|
||||
|
||||
HValue* EnforceNumberType(HValue* number, Type* expected);
|
||||
HValue* TruncateToNumber(HValue* value, Type** expected);
|
||||
|
@ -522,7 +522,7 @@ static void Generate_CheckStackOverflow(MacroAssembler* masm,
|
||||
__ SmiTag(eax);
|
||||
}
|
||||
__ push(eax);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
|
||||
__ bind(&okay);
|
||||
}
|
||||
@ -660,7 +660,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
ExternalReference::address_of_real_stack_limit(masm->isolate());
|
||||
__ cmp(ecx, Operand::StaticVariable(stack_limit));
|
||||
__ j(above_equal, &ok);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
|
||||
// If ok, push undefined as the initial value for all register file entries.
|
||||
@ -1081,12 +1081,12 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
__ push(edi); // re-add proxy object as additional argument
|
||||
__ push(edx);
|
||||
__ inc(eax);
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinEntry(edx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&non_proxy);
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinEntry(edx, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ bind(&function);
|
||||
@ -1183,9 +1183,10 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ push(Operand(ebp, kFunctionOffset)); // push this
|
||||
__ push(Operand(ebp, kArgumentsOffset)); // push arguments
|
||||
if (targetIsArgument) {
|
||||
__ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged);
|
||||
@ -1272,7 +1273,7 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ push(edi); // add function proxy as last argument
|
||||
__ inc(eax);
|
||||
__ Move(ebx, Immediate(0));
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinEntry(edx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
@ -1317,7 +1318,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
|
||||
__ push(Operand(ebp, kFunctionOffset));
|
||||
__ push(Operand(ebp, kArgumentsOffset));
|
||||
__ push(Operand(ebp, kNewTargetOffset));
|
||||
__ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged);
|
||||
|
||||
@ -1521,7 +1523,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ push(edi); // Preserve the function.
|
||||
__ push(eax);
|
||||
__ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_STRING_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ pop(edi);
|
||||
}
|
||||
__ mov(ebx, eax);
|
||||
@ -1723,7 +1725,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ int3();
|
||||
}
|
||||
}
|
||||
|
@ -1896,12 +1896,13 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
__ push(ecx);
|
||||
__ TailCallRuntime(Runtime::kStrictEquals, 2, 1);
|
||||
} else {
|
||||
Builtins::JavaScript builtin;
|
||||
int native_context_index;
|
||||
if (cc == equal) {
|
||||
builtin = Builtins::EQUALS;
|
||||
native_context_index = Context::EQUALS_BUILTIN_INDEX;
|
||||
} else {
|
||||
builtin =
|
||||
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||
native_context_index = is_strong(strength())
|
||||
? Context::COMPARE_STRONG_BUILTIN_INDEX
|
||||
: Context::COMPARE_BUILTIN_INDEX;
|
||||
__ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
|
||||
}
|
||||
|
||||
@ -1910,7 +1911,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
|
||||
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
|
||||
// tagged as a small integer.
|
||||
__ InvokeBuiltin(builtin, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(native_context_index, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
__ bind(&miss);
|
||||
@ -2075,7 +2076,7 @@ static void EmitSlowCase(Isolate* isolate,
|
||||
__ push(ecx);
|
||||
__ Move(eax, Immediate(argc + 1));
|
||||
__ Move(ebx, Immediate(0));
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinEntry(edx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
{
|
||||
Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
|
||||
__ jmp(adaptor, RelocInfo::CODE_TARGET);
|
||||
@ -2087,7 +2088,7 @@ static void EmitSlowCase(Isolate* isolate,
|
||||
__ mov(Operand(esp, (argc + 1) * kPointerSize), edi);
|
||||
__ Move(eax, Immediate(argc));
|
||||
__ Move(ebx, Immediate(0));
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinEntry(edx, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
|
||||
__ jmp(adaptor, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
@ -2231,11 +2232,13 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(&slow);
|
||||
__ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
|
||||
__ j(not_equal, &non_function_call);
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinEntry(edx,
|
||||
Context::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ jmp(&do_call);
|
||||
|
||||
__ bind(&non_function_call);
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinEntry(edx,
|
||||
Context::CALL_NON_FUNCTION_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ bind(&do_call);
|
||||
if (IsSuperConstructorCall()) {
|
||||
__ Drop(1);
|
||||
@ -3268,7 +3271,7 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
|
||||
__ pop(ecx); // Pop return address.
|
||||
__ push(eax); // Push argument.
|
||||
__ push(ecx); // Push return address.
|
||||
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_NUMBER_BUILTIN_INDEX, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2056,8 +2056,7 @@ void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper) {
|
||||
// You can't call a builtin without a valid frame.
|
||||
DCHECK(flag == JUMP_FUNCTION || has_frame());
|
||||
@ -2066,26 +2065,26 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
// arguments match the expected number of arguments. Fake a
|
||||
// parameter count to avoid emitting code to do the check.
|
||||
ParameterCount expected(0);
|
||||
GetBuiltinFunction(edi, id);
|
||||
GetBuiltinFunction(edi, native_context_index);
|
||||
InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
|
||||
expected, expected, flag, call_wrapper);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinFunction(Register target,
|
||||
Builtins::JavaScript id) {
|
||||
int native_context_index) {
|
||||
// Load the JavaScript builtin function from the builtins object.
|
||||
mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
||||
mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
|
||||
mov(target, FieldOperand(target,
|
||||
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
|
||||
mov(target, GlobalObjectOperand());
|
||||
mov(target, FieldOperand(target, GlobalObject::kNativeContextOffset));
|
||||
mov(target, ContextOperand(target, native_context_index));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
|
||||
void MacroAssembler::GetBuiltinEntry(Register target,
|
||||
int native_context_index) {
|
||||
DCHECK(!target.is(edi));
|
||||
// Load the JavaScript builtin function from the builtins object.
|
||||
GetBuiltinFunction(edi, id);
|
||||
GetBuiltinFunction(edi, native_context_index);
|
||||
// Load the code entry point from the function into the target register.
|
||||
mov(target, FieldOperand(edi, JSFunction::kCodeEntryOffset));
|
||||
}
|
||||
|
@ -357,17 +357,15 @@ class MacroAssembler: public Assembler {
|
||||
InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper);
|
||||
|
||||
// Invoke specified builtin JavaScript function. Adds an entry to
|
||||
// the unresolved list if the name does not resolve.
|
||||
void InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
// Invoke specified builtin JavaScript function.
|
||||
void InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper = NullCallWrapper());
|
||||
|
||||
// Store the function for the given builtin in the target register.
|
||||
void GetBuiltinFunction(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinFunction(Register target, int native_context_index);
|
||||
|
||||
// Store the code object for the given builtin in the target register.
|
||||
void GetBuiltinEntry(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinEntry(Register target, int native_context_index);
|
||||
|
||||
// Expression support
|
||||
// cvtsi2sd instruction only writes to the low 64-bit of dst register, which
|
||||
|
73
src/ic/ic.cc
73
src/ic/ic.cc
@ -2642,8 +2642,8 @@ MaybeHandle<Object> BinaryOpIC::Transition(
|
||||
BinaryOpICState state(isolate(), target()->extra_ic_state());
|
||||
|
||||
// Compute the actual result using the builtin for the binary operation.
|
||||
Object* builtin = isolate()->js_builtins_object()->javascript_builtin(
|
||||
TokenToJSBuiltin(state.op(), state.strength()));
|
||||
Object* builtin = isolate()->native_context()->get(
|
||||
TokenToContextIndex(state.op(), state.strength()));
|
||||
Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate());
|
||||
Handle<Object> result;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
@ -2882,37 +2882,58 @@ RUNTIME_FUNCTION(Runtime_Unreachable) {
|
||||
}
|
||||
|
||||
|
||||
Builtins::JavaScript BinaryOpIC::TokenToJSBuiltin(Token::Value op,
|
||||
Strength strength) {
|
||||
int BinaryOpIC::TokenToContextIndex(Token::Value op, Strength strength) {
|
||||
if (is_strong(strength)) {
|
||||
switch (op) {
|
||||
default: UNREACHABLE();
|
||||
case Token::ADD: return Builtins::ADD_STRONG;
|
||||
case Token::SUB: return Builtins::SUB_STRONG;
|
||||
case Token::MUL: return Builtins::MUL_STRONG;
|
||||
case Token::DIV: return Builtins::DIV_STRONG;
|
||||
case Token::MOD: return Builtins::MOD_STRONG;
|
||||
case Token::BIT_OR: return Builtins::BIT_OR_STRONG;
|
||||
case Token::BIT_AND: return Builtins::BIT_AND_STRONG;
|
||||
case Token::BIT_XOR: return Builtins::BIT_XOR_STRONG;
|
||||
case Token::SAR: return Builtins::SAR_STRONG;
|
||||
case Token::SHR: return Builtins::SHR_STRONG;
|
||||
case Token::SHL: return Builtins::SHL_STRONG;
|
||||
case Token::ADD:
|
||||
return Context::ADD_STRONG_BUILTIN_INDEX;
|
||||
case Token::SUB:
|
||||
return Context::SUB_STRONG_BUILTIN_INDEX;
|
||||
case Token::MUL:
|
||||
return Context::MUL_STRONG_BUILTIN_INDEX;
|
||||
case Token::DIV:
|
||||
return Context::DIV_STRONG_BUILTIN_INDEX;
|
||||
case Token::MOD:
|
||||
return Context::MOD_STRONG_BUILTIN_INDEX;
|
||||
case Token::BIT_OR:
|
||||
return Context::BIT_OR_STRONG_BUILTIN_INDEX;
|
||||
case Token::BIT_AND:
|
||||
return Context::BIT_AND_STRONG_BUILTIN_INDEX;
|
||||
case Token::BIT_XOR:
|
||||
return Context::BIT_XOR_STRONG_BUILTIN_INDEX;
|
||||
case Token::SAR:
|
||||
return Context::SAR_STRONG_BUILTIN_INDEX;
|
||||
case Token::SHR:
|
||||
return Context::SHR_STRONG_BUILTIN_INDEX;
|
||||
case Token::SHL:
|
||||
return Context::SHL_STRONG_BUILTIN_INDEX;
|
||||
}
|
||||
} else {
|
||||
switch (op) {
|
||||
default: UNREACHABLE();
|
||||
case Token::ADD: return Builtins::ADD;
|
||||
case Token::SUB: return Builtins::SUB;
|
||||
case Token::MUL: return Builtins::MUL;
|
||||
case Token::DIV: return Builtins::DIV;
|
||||
case Token::MOD: return Builtins::MOD;
|
||||
case Token::BIT_OR: return Builtins::BIT_OR;
|
||||
case Token::BIT_AND: return Builtins::BIT_AND;
|
||||
case Token::BIT_XOR: return Builtins::BIT_XOR;
|
||||
case Token::SAR: return Builtins::SAR;
|
||||
case Token::SHR: return Builtins::SHR;
|
||||
case Token::SHL: return Builtins::SHL;
|
||||
case Token::ADD:
|
||||
return Context::ADD_BUILTIN_INDEX;
|
||||
case Token::SUB:
|
||||
return Context::SUB_BUILTIN_INDEX;
|
||||
case Token::MUL:
|
||||
return Context::MUL_BUILTIN_INDEX;
|
||||
case Token::DIV:
|
||||
return Context::DIV_BUILTIN_INDEX;
|
||||
case Token::MOD:
|
||||
return Context::MOD_BUILTIN_INDEX;
|
||||
case Token::BIT_OR:
|
||||
return Context::BIT_OR_BUILTIN_INDEX;
|
||||
case Token::BIT_AND:
|
||||
return Context::BIT_AND_BUILTIN_INDEX;
|
||||
case Token::BIT_XOR:
|
||||
return Context::BIT_XOR_BUILTIN_INDEX;
|
||||
case Token::SAR:
|
||||
return Context::SAR_BUILTIN_INDEX;
|
||||
case Token::SHR:
|
||||
return Context::SHR_BUILTIN_INDEX;
|
||||
case Token::SHL:
|
||||
return Context::SHL_BUILTIN_INDEX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -610,8 +610,7 @@ class BinaryOpIC : public IC {
|
||||
public:
|
||||
explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
|
||||
|
||||
static Builtins::JavaScript TokenToJSBuiltin(Token::Value op,
|
||||
Strength strength);
|
||||
static int TokenToContextIndex(Token::Value op, Strength strength);
|
||||
|
||||
MaybeHandle<Object> Transition(Handle<AllocationSite> allocation_site,
|
||||
Handle<Object> left,
|
||||
|
@ -183,14 +183,14 @@ void Interpreter::DoStar(compiler::InterpreterAssembler* assembler) {
|
||||
}
|
||||
|
||||
|
||||
void Interpreter::DoBinaryOp(Builtins::JavaScript binop_builtin,
|
||||
void Interpreter::DoBinaryOp(int builtin_context_index,
|
||||
compiler::InterpreterAssembler* assembler) {
|
||||
// TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized
|
||||
// operations, instead of calling builtins directly.
|
||||
Node* reg_index = __ BytecodeOperandReg(0);
|
||||
Node* lhs = __ LoadRegister(reg_index);
|
||||
Node* rhs = __ GetAccumulator();
|
||||
Node* result = __ CallJSBuiltin(binop_builtin, lhs, rhs);
|
||||
Node* result = __ CallJSBuiltin(builtin_context_index, lhs, rhs);
|
||||
__ SetAccumulator(result);
|
||||
__ Dispatch();
|
||||
}
|
||||
@ -200,7 +200,7 @@ void Interpreter::DoBinaryOp(Builtins::JavaScript binop_builtin,
|
||||
//
|
||||
// Add register <src> to accumulator.
|
||||
void Interpreter::DoAdd(compiler::InterpreterAssembler* assembler) {
|
||||
DoBinaryOp(Builtins::ADD, assembler);
|
||||
DoBinaryOp(Context::ADD_BUILTIN_INDEX, assembler);
|
||||
}
|
||||
|
||||
|
||||
@ -208,7 +208,7 @@ void Interpreter::DoAdd(compiler::InterpreterAssembler* assembler) {
|
||||
//
|
||||
// Subtract register <src> from accumulator.
|
||||
void Interpreter::DoSub(compiler::InterpreterAssembler* assembler) {
|
||||
DoBinaryOp(Builtins::SUB, assembler);
|
||||
DoBinaryOp(Context::SUB_BUILTIN_INDEX, assembler);
|
||||
}
|
||||
|
||||
|
||||
@ -216,7 +216,7 @@ void Interpreter::DoSub(compiler::InterpreterAssembler* assembler) {
|
||||
//
|
||||
// Multiply accumulator by register <src>.
|
||||
void Interpreter::DoMul(compiler::InterpreterAssembler* assembler) {
|
||||
DoBinaryOp(Builtins::MUL, assembler);
|
||||
DoBinaryOp(Context::MUL_BUILTIN_INDEX, assembler);
|
||||
}
|
||||
|
||||
|
||||
@ -224,7 +224,7 @@ void Interpreter::DoMul(compiler::InterpreterAssembler* assembler) {
|
||||
//
|
||||
// Divide register <src> by accumulator.
|
||||
void Interpreter::DoDiv(compiler::InterpreterAssembler* assembler) {
|
||||
DoBinaryOp(Builtins::DIV, assembler);
|
||||
DoBinaryOp(Context::DIV_BUILTIN_INDEX, assembler);
|
||||
}
|
||||
|
||||
|
||||
@ -232,7 +232,7 @@ void Interpreter::DoDiv(compiler::InterpreterAssembler* assembler) {
|
||||
//
|
||||
// Modulo register <src> by accumulator.
|
||||
void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) {
|
||||
DoBinaryOp(Builtins::MOD, assembler);
|
||||
DoBinaryOp(Context::MOD_BUILTIN_INDEX, assembler);
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,7 +48,7 @@ class Interpreter {
|
||||
#undef DECLARE_BYTECODE_HANDLER_GENERATOR
|
||||
|
||||
// Generates code to perform the binary operations via |binop_builtin|.
|
||||
void DoBinaryOp(Builtins::JavaScript binop_builtin,
|
||||
void DoBinaryOp(int builtin_context_index,
|
||||
compiler::InterpreterAssembler* assembler);
|
||||
|
||||
bool IsInterpreterTableInitialized(Handle<FixedArray> handler_table);
|
||||
|
@ -658,10 +658,6 @@ class Isolate {
|
||||
return context()->global_proxy();
|
||||
}
|
||||
|
||||
Handle<JSBuiltinsObject> js_builtins_object() {
|
||||
return Handle<JSBuiltinsObject>(thread_local_top_.context_->builtins());
|
||||
}
|
||||
|
||||
static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
|
||||
void FreeThreadResources() { thread_local_top_.Free(); }
|
||||
|
||||
|
@ -242,7 +242,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ push(a0);
|
||||
__ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_STRING_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
__ pop(function);
|
||||
__ mov(argument, v0);
|
||||
@ -763,7 +763,7 @@ static void Generate_CheckStackOverflow(MacroAssembler* masm,
|
||||
__ SmiTag(argc);
|
||||
}
|
||||
__ Push(a1, argc);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
|
||||
__ bind(&okay);
|
||||
}
|
||||
@ -912,7 +912,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ Subu(t1, sp, Operand(t0));
|
||||
__ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
|
||||
__ Branch(&ok, hs, t1, Operand(a2));
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
|
||||
// If ok, push undefined as the initial value for all register file entries.
|
||||
@ -1401,12 +1401,12 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
|
||||
__ push(a1); // Re-add proxy object as additional argument.
|
||||
__ Addu(a0, a0, Operand(1));
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(a1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&non_proxy);
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinFunction(a1, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ bind(&function);
|
||||
@ -1496,9 +1496,10 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ push(a0);
|
||||
// Returns (in v0) number of arguments to copy to stack as Smi.
|
||||
if (targetIsArgument) {
|
||||
__ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
|
||||
// Returns the result in v0.
|
||||
@ -1590,7 +1591,7 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ push(a1); // Add function proxy as last argument.
|
||||
__ Addu(a0, a0, Operand(1));
|
||||
__ li(a2, Operand(0, RelocInfo::NONE32));
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(a1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
// Tear down the internal frame and remove function, receiver and args.
|
||||
@ -1628,7 +1629,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
|
||||
__ lw(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target
|
||||
__ push(a0);
|
||||
// Returns argument count in v0.
|
||||
__ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
|
||||
// Returns result in v0.
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged);
|
||||
@ -1871,7 +1873,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ break_(0xCC);
|
||||
}
|
||||
}
|
||||
|
@ -729,12 +729,13 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
if (cc == eq && strict()) {
|
||||
__ TailCallRuntime(Runtime::kStrictEquals, 2, 1);
|
||||
} else {
|
||||
Builtins::JavaScript native;
|
||||
int context_index;
|
||||
if (cc == eq) {
|
||||
native = Builtins::EQUALS;
|
||||
context_index = Context::EQUALS_BUILTIN_INDEX;
|
||||
} else {
|
||||
native =
|
||||
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||
context_index = is_strong(strength())
|
||||
? Context::COMPARE_STRONG_BUILTIN_INDEX
|
||||
: Context::COMPARE_BUILTIN_INDEX;
|
||||
int ncr; // NaN compare result.
|
||||
if (cc == lt || cc == le) {
|
||||
ncr = GREATER;
|
||||
@ -748,7 +749,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
|
||||
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
|
||||
// tagged as a small integer.
|
||||
__ InvokeBuiltin(native, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(context_index, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
__ bind(&miss);
|
||||
@ -2558,7 +2559,7 @@ static void EmitSlowCase(MacroAssembler* masm,
|
||||
__ push(a1); // put proxy as additional argument
|
||||
__ li(a0, Operand(argc + 1, RelocInfo::NONE32));
|
||||
__ mov(a2, zero_reg);
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(a1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
{
|
||||
Handle<Code> adaptor =
|
||||
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
|
||||
@ -2571,7 +2572,7 @@ static void EmitSlowCase(MacroAssembler* masm,
|
||||
__ sw(a1, MemOperand(sp, argc * kPointerSize));
|
||||
__ li(a0, Operand(argc)); // Set up the number of arguments.
|
||||
__ mov(a2, zero_reg);
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinFunction(a1, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
@ -2710,11 +2711,13 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
Label do_call;
|
||||
__ bind(&slow);
|
||||
__ Branch(&non_function_call, ne, t1, Operand(JS_FUNCTION_PROXY_TYPE));
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinFunction(
|
||||
a1, Context::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ jmp(&do_call);
|
||||
|
||||
__ bind(&non_function_call);
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinFunction(
|
||||
a1, Context::CALL_NON_FUNCTION_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ bind(&do_call);
|
||||
// Set expected number of arguments to zero (not changing r0).
|
||||
__ li(a2, Operand(0, RelocInfo::NONE32));
|
||||
@ -3410,7 +3413,7 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(¬_oddball);
|
||||
|
||||
__ push(a0); // Push argument.
|
||||
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_NUMBER_BUILTIN_INDEX, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4591,13 +4591,12 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper) {
|
||||
// You can't call a builtin without a valid frame.
|
||||
DCHECK(flag == JUMP_FUNCTION || has_frame());
|
||||
|
||||
GetBuiltinEntry(t9, id);
|
||||
GetBuiltinEntry(t9, native_context_index);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
call_wrapper.BeforeCall(CallSize(t9));
|
||||
Call(t9);
|
||||
@ -4610,19 +4609,19 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinFunction(Register target,
|
||||
Builtins::JavaScript id) {
|
||||
int native_context_index) {
|
||||
// Load the builtins object into target register.
|
||||
lw(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
||||
lw(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset));
|
||||
lw(target, FieldMemOperand(target, GlobalObject::kNativeContextOffset));
|
||||
// Load the JavaScript builtin function from the builtins object.
|
||||
lw(target, FieldMemOperand(target,
|
||||
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
|
||||
lw(target, ContextOperand(target, native_context_index));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
|
||||
void MacroAssembler::GetBuiltinEntry(Register target,
|
||||
int native_context_index) {
|
||||
DCHECK(!target.is(a1));
|
||||
GetBuiltinFunction(a1, id);
|
||||
GetBuiltinFunction(a1, native_context_index);
|
||||
// Load the code entry point from the builtins object.
|
||||
lw(target, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
|
||||
}
|
||||
|
@ -1324,18 +1324,16 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
|
||||
void JumpToExternalReference(const ExternalReference& builtin,
|
||||
BranchDelaySlot bd = PROTECT);
|
||||
|
||||
// Invoke specified builtin JavaScript function. Adds an entry to
|
||||
// the unresolved list if the name does not resolve.
|
||||
void InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
// Invoke specified builtin JavaScript function.
|
||||
void InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper = NullCallWrapper());
|
||||
|
||||
// Store the code object for the given builtin in the target register and
|
||||
// setup the function in a1.
|
||||
void GetBuiltinEntry(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinEntry(Register target, int native_context_index);
|
||||
|
||||
// Store the function for the given builtin in the target register.
|
||||
void GetBuiltinFunction(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinFunction(Register target, int native_context_index);
|
||||
|
||||
struct Unresolved {
|
||||
int pc;
|
||||
@ -1660,10 +1658,6 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
|
||||
InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper);
|
||||
|
||||
// Get the code for the given builtin. Returns if able to resolve
|
||||
// the function in the 'resolved' flag.
|
||||
Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
|
||||
|
||||
void InitializeNewString(Register string,
|
||||
Register length,
|
||||
Heap::RootListIndex map_index,
|
||||
|
@ -240,7 +240,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ push(a0);
|
||||
__ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_STRING_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
__ pop(function);
|
||||
__ mov(argument, v0);
|
||||
@ -762,7 +762,7 @@ static void Generate_CheckStackOverflow(MacroAssembler* masm,
|
||||
__ SmiTag(argc);
|
||||
}
|
||||
__ Push(a1, argc);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
|
||||
__ bind(&okay);
|
||||
}
|
||||
@ -909,7 +909,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ Dsubu(a5, sp, Operand(a4));
|
||||
__ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
|
||||
__ Branch(&ok, hs, a5, Operand(a2));
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
|
||||
// If ok, push undefined as the initial value for all register file entries.
|
||||
@ -1396,12 +1396,12 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
|
||||
__ push(a1); // Re-add proxy object as additional argument.
|
||||
__ Daddu(a0, a0, Operand(1));
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(a1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&non_proxy);
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinFunction(a1, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ bind(&function);
|
||||
@ -1493,9 +1493,10 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
|
||||
// Returns (in v0) number of arguments to copy to stack as Smi.
|
||||
if (targetIsArgument) {
|
||||
__ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
|
||||
// Returns the result in v0.
|
||||
@ -1587,7 +1588,7 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ push(a1); // Add function proxy as last argument.
|
||||
__ Daddu(a0, a0, Operand(1));
|
||||
__ li(a2, Operand(0, RelocInfo::NONE32));
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(a1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
// Tear down the internal frame and remove function, receiver and args.
|
||||
@ -1625,7 +1626,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
|
||||
__ ld(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target
|
||||
__ push(a0);
|
||||
// Returns argument count in v0.
|
||||
__ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
|
||||
// Returns result in v0.
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged);
|
||||
@ -1869,7 +1871,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ break_(0xCC);
|
||||
}
|
||||
}
|
||||
|
@ -724,12 +724,13 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
if (cc == eq && strict()) {
|
||||
__ TailCallRuntime(Runtime::kStrictEquals, 2, 1);
|
||||
} else {
|
||||
Builtins::JavaScript native;
|
||||
int context_index;
|
||||
if (cc == eq) {
|
||||
native = Builtins::EQUALS;
|
||||
context_index = Context::EQUALS_BUILTIN_INDEX;
|
||||
} else {
|
||||
native =
|
||||
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||
context_index = is_strong(strength())
|
||||
? Context::COMPARE_STRONG_BUILTIN_INDEX
|
||||
: Context::COMPARE_BUILTIN_INDEX;
|
||||
int ncr; // NaN compare result.
|
||||
if (cc == lt || cc == le) {
|
||||
ncr = GREATER;
|
||||
@ -743,7 +744,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
|
||||
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
|
||||
// tagged as a small integer.
|
||||
__ InvokeBuiltin(native, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(context_index, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
__ bind(&miss);
|
||||
@ -2597,7 +2598,7 @@ static void EmitSlowCase(MacroAssembler* masm,
|
||||
__ push(a1); // put proxy as additional argument
|
||||
__ li(a0, Operand(argc + 1, RelocInfo::NONE32));
|
||||
__ mov(a2, zero_reg);
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(a1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
{
|
||||
Handle<Code> adaptor =
|
||||
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
|
||||
@ -2610,7 +2611,7 @@ static void EmitSlowCase(MacroAssembler* masm,
|
||||
__ sd(a1, MemOperand(sp, argc * kPointerSize));
|
||||
__ li(a0, Operand(argc)); // Set up the number of arguments.
|
||||
__ mov(a2, zero_reg);
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinFunction(a1, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
@ -2747,11 +2748,13 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
Label do_call;
|
||||
__ bind(&slow);
|
||||
__ Branch(&non_function_call, ne, a5, Operand(JS_FUNCTION_PROXY_TYPE));
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinFunction(
|
||||
a1, Context::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ jmp(&do_call);
|
||||
|
||||
__ bind(&non_function_call);
|
||||
__ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinFunction(
|
||||
a1, Context::CALL_NON_FUNCTION_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ bind(&do_call);
|
||||
// Set expected number of arguments to zero (not changing r0).
|
||||
__ li(a2, Operand(0, RelocInfo::NONE32));
|
||||
@ -3442,7 +3445,7 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(¬_oddball);
|
||||
|
||||
__ push(a0); // Push argument.
|
||||
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_NUMBER_BUILTIN_INDEX, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4722,13 +4722,12 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper) {
|
||||
// You can't call a builtin without a valid frame.
|
||||
DCHECK(flag == JUMP_FUNCTION || has_frame());
|
||||
|
||||
GetBuiltinEntry(t9, id);
|
||||
GetBuiltinEntry(t9, native_context_index);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
call_wrapper.BeforeCall(CallSize(t9));
|
||||
Call(t9);
|
||||
@ -4741,19 +4740,19 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinFunction(Register target,
|
||||
Builtins::JavaScript id) {
|
||||
int native_context_index) {
|
||||
// Load the builtins object into target register.
|
||||
ld(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
||||
ld(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset));
|
||||
ld(target, FieldMemOperand(target, GlobalObject::kNativeContextOffset));
|
||||
// Load the JavaScript builtin function from the builtins object.
|
||||
ld(target, FieldMemOperand(target,
|
||||
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
|
||||
ld(target, ContextOperand(target, native_context_index));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
|
||||
void MacroAssembler::GetBuiltinEntry(Register target,
|
||||
int native_context_index) {
|
||||
DCHECK(!target.is(a1));
|
||||
GetBuiltinFunction(a1, id);
|
||||
GetBuiltinFunction(a1, native_context_index);
|
||||
// Load the code entry point from the builtins object.
|
||||
ld(target, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
|
||||
}
|
||||
|
@ -1371,18 +1371,16 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
|
||||
void JumpToExternalReference(const ExternalReference& builtin,
|
||||
BranchDelaySlot bd = PROTECT);
|
||||
|
||||
// Invoke specified builtin JavaScript function. Adds an entry to
|
||||
// the unresolved list if the name does not resolve.
|
||||
void InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
// Invoke specified builtin JavaScript function.
|
||||
void InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper = NullCallWrapper());
|
||||
|
||||
// Store the code object for the given builtin in the target register and
|
||||
// setup the function in a1.
|
||||
void GetBuiltinEntry(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinEntry(Register target, int native_context_index);
|
||||
|
||||
// Store the function for the given builtin in the target register.
|
||||
void GetBuiltinFunction(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinFunction(Register target, int native_context_index);
|
||||
|
||||
struct Unresolved {
|
||||
int pc;
|
||||
@ -1746,10 +1744,6 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
|
||||
InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper);
|
||||
|
||||
// Get the code for the given builtin. Returns if able to resolve
|
||||
// the function in the 'resolved' flag.
|
||||
Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
|
||||
|
||||
void InitializeNewString(Register string,
|
||||
Register length,
|
||||
Heap::RootListIndex map_index,
|
||||
|
@ -6249,20 +6249,6 @@ int JSFunction::NumberOfLiterals() {
|
||||
}
|
||||
|
||||
|
||||
Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
|
||||
DCHECK(id < kJSBuiltinsCount); // id is unsigned.
|
||||
return READ_FIELD(this, OffsetOfFunctionWithId(id));
|
||||
}
|
||||
|
||||
|
||||
void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
|
||||
Object* value) {
|
||||
DCHECK(id < kJSBuiltinsCount); // id is unsigned.
|
||||
WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
|
||||
WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
|
||||
}
|
||||
|
||||
|
||||
ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
|
||||
ACCESSORS(JSProxy, hash, Object, kHashOffset)
|
||||
ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
|
||||
|
@ -7151,27 +7151,14 @@ class JSGlobalObject: public GlobalObject {
|
||||
// JavaScript.
|
||||
class JSBuiltinsObject: public GlobalObject {
|
||||
public:
|
||||
// Accessors for the runtime routines written in JavaScript.
|
||||
inline Object* javascript_builtin(Builtins::JavaScript id);
|
||||
inline void set_javascript_builtin(Builtins::JavaScript id, Object* value);
|
||||
|
||||
DECLARE_CAST(JSBuiltinsObject)
|
||||
|
||||
// Dispatched behavior.
|
||||
DECLARE_PRINTER(JSBuiltinsObject)
|
||||
DECLARE_VERIFIER(JSBuiltinsObject)
|
||||
|
||||
// Layout description. The size of the builtins object includes
|
||||
// room for two pointers per runtime routine written in javascript
|
||||
// (function and code object).
|
||||
static const int kJSBuiltinsCount = Builtins::id_count;
|
||||
static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize;
|
||||
static const int kSize =
|
||||
GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize);
|
||||
|
||||
static int OffsetOfFunctionWithId(Builtins::JavaScript id) {
|
||||
return kJSBuiltinsOffset + id * kPointerSize;
|
||||
}
|
||||
// Layout description.
|
||||
static const int kSize = GlobalObject::kHeaderSize;
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject);
|
||||
|
@ -234,7 +234,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
|
||||
{
|
||||
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
|
||||
__ push(r3);
|
||||
__ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_STRING_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
__ pop(function);
|
||||
__ mr(argument, r3);
|
||||
@ -760,7 +760,7 @@ static void Generate_CheckStackOverflow(MacroAssembler* masm,
|
||||
__ SmiTag(argc);
|
||||
}
|
||||
__ Push(r4, argc);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
|
||||
__ bind(&okay);
|
||||
}
|
||||
@ -909,7 +909,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ LoadRoot(r0, Heap::kRealStackLimitRootIndex);
|
||||
__ cmp(r6, r0);
|
||||
__ bge(&ok);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
|
||||
// If ok, push undefined as the initial value for all register file entries.
|
||||
@ -1431,12 +1431,12 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
|
||||
__ push(r4); // re-add proxy object as additional argument
|
||||
__ addi(r3, r3, Operand(1));
|
||||
__ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(r4, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&non_proxy);
|
||||
__ GetBuiltinFunction(r4, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinFunction(r4, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ bind(&function);
|
||||
@ -1527,9 +1527,10 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ LoadP(r3, MemOperand(fp, kArgumentsOffset)); // get the args array
|
||||
__ push(r3);
|
||||
if (targetIsArgument) {
|
||||
__ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, r3, kArgcIsSmiTagged);
|
||||
@ -1630,7 +1631,7 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ push(r4); // add function proxy as last argument
|
||||
__ addi(r3, r3, Operand(1));
|
||||
__ li(r5, Operand::Zero());
|
||||
__ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(r4, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
@ -1667,7 +1668,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
|
||||
__ push(r3);
|
||||
__ LoadP(r3, MemOperand(fp, kNewTargetOffset)); // get the new.target
|
||||
__ push(r3);
|
||||
__ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, r3, kArgcIsSmiTagged);
|
||||
|
||||
@ -1917,7 +1919,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bkpt(0);
|
||||
}
|
||||
}
|
||||
|
@ -709,12 +709,13 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
if (cc == eq && strict()) {
|
||||
__ TailCallRuntime(Runtime::kStrictEquals, 2, 1);
|
||||
} else {
|
||||
Builtins::JavaScript native;
|
||||
int context_index;
|
||||
if (cc == eq) {
|
||||
native = Builtins::EQUALS;
|
||||
context_index = Context::EQUALS_BUILTIN_INDEX;
|
||||
} else {
|
||||
native =
|
||||
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||
context_index = is_strong(strength())
|
||||
? Context::COMPARE_STRONG_BUILTIN_INDEX
|
||||
: Context::COMPARE_BUILTIN_INDEX;
|
||||
int ncr; // NaN compare result
|
||||
if (cc == lt || cc == le) {
|
||||
ncr = GREATER;
|
||||
@ -728,7 +729,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
|
||||
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
|
||||
// tagged as a small integer.
|
||||
__ InvokeBuiltin(native, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(context_index, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
__ bind(&miss);
|
||||
@ -1549,12 +1550,12 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
|
||||
if (HasArgsInRegisters()) {
|
||||
__ Push(r3, r4);
|
||||
}
|
||||
__ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(Context::INSTANCE_OF_BUILTIN_INDEX, JUMP_FUNCTION);
|
||||
} else {
|
||||
{
|
||||
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(r3, r4);
|
||||
__ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::INSTANCE_OF_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
if (CpuFeatures::IsSupported(ISELECT)) {
|
||||
__ cmpi(r3, Operand::Zero());
|
||||
@ -2700,7 +2701,7 @@ static void EmitSlowCase(MacroAssembler* masm, int argc, Label* non_function) {
|
||||
__ push(r4); // put proxy as additional argument
|
||||
__ li(r3, Operand(argc + 1));
|
||||
__ li(r5, Operand::Zero());
|
||||
__ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinFunction(r4, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
{
|
||||
Handle<Code> adaptor =
|
||||
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
|
||||
@ -2713,7 +2714,7 @@ static void EmitSlowCase(MacroAssembler* masm, int argc, Label* non_function) {
|
||||
__ StoreP(r4, MemOperand(sp, argc * kPointerSize), r0);
|
||||
__ li(r3, Operand(argc)); // Set up the number of arguments.
|
||||
__ li(r5, Operand::Zero());
|
||||
__ GetBuiltinFunction(r4, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinFunction(r4, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
@ -2858,11 +2859,13 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
STATIC_ASSERT(JS_FUNCTION_PROXY_TYPE < 0xffffu);
|
||||
__ cmpi(r8, Operand(JS_FUNCTION_PROXY_TYPE));
|
||||
__ bne(&non_function_call);
|
||||
__ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinFunction(
|
||||
r4, Context::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ b(&do_call);
|
||||
|
||||
__ bind(&non_function_call);
|
||||
__ GetBuiltinFunction(r4, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinFunction(
|
||||
r4, Context::CALL_NON_FUNCTION_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ bind(&do_call);
|
||||
// Set expected number of arguments to zero (not changing r3).
|
||||
__ li(r5, Operand::Zero());
|
||||
@ -3531,7 +3534,7 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(¬_oddball);
|
||||
|
||||
__ push(r3); // Push argument.
|
||||
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_NUMBER_BUILTIN_INDEX, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2312,12 +2312,12 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag,
|
||||
void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper) {
|
||||
// You can't call a builtin without a valid frame.
|
||||
DCHECK(flag == JUMP_FUNCTION || has_frame());
|
||||
|
||||
GetBuiltinEntry(ip, id);
|
||||
GetBuiltinEntry(ip, native_context_index);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
call_wrapper.BeforeCall(CallSize(ip));
|
||||
CallJSEntry(ip);
|
||||
@ -2330,21 +2330,20 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag,
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinFunction(Register target,
|
||||
Builtins::JavaScript id) {
|
||||
int native_context_index) {
|
||||
// Load the builtins object into target register.
|
||||
LoadP(target,
|
||||
MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
||||
LoadP(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset));
|
||||
LoadP(target, FieldMemOperand(target, GlobalObject::kNativeContextOffset));
|
||||
// Load the JavaScript builtin function from the builtins object.
|
||||
LoadP(target,
|
||||
FieldMemOperand(target, JSBuiltinsObject::OffsetOfFunctionWithId(id)),
|
||||
r0);
|
||||
LoadP(target, ContextOperand(target, native_context_index), r0);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
|
||||
void MacroAssembler::GetBuiltinEntry(Register target,
|
||||
int native_context_index) {
|
||||
DCHECK(!target.is(r4));
|
||||
GetBuiltinFunction(r4, id);
|
||||
GetBuiltinFunction(r4, native_context_index);
|
||||
// Load the code entry point from the builtins object.
|
||||
LoadP(target, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
|
||||
}
|
||||
|
@ -982,17 +982,16 @@ class MacroAssembler : public Assembler {
|
||||
// Jump to a runtime routine.
|
||||
void JumpToExternalReference(const ExternalReference& builtin);
|
||||
|
||||
// Invoke specified builtin JavaScript function. Adds an entry to
|
||||
// the unresolved list if the name does not resolve.
|
||||
void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag,
|
||||
// Invoke specified builtin JavaScript function.
|
||||
void InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper = NullCallWrapper());
|
||||
|
||||
// Store the code object for the given builtin in the target register and
|
||||
// setup the function in r1.
|
||||
void GetBuiltinEntry(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinEntry(Register target, int native_context_index);
|
||||
|
||||
// Store the function for the given builtin in the target register.
|
||||
void GetBuiltinFunction(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinFunction(Register target, int native_context_index);
|
||||
|
||||
Handle<Object> CodeObject() {
|
||||
DCHECK(!code_object_.is_null());
|
||||
|
@ -837,48 +837,48 @@ $toPositiveInteger = ToPositiveInteger;
|
||||
$toPrimitive = ToPrimitive;
|
||||
$toString = ToString;
|
||||
|
||||
%InstallJSBuiltins({
|
||||
EQUALS,
|
||||
COMPARE,
|
||||
COMPARE_STRONG,
|
||||
ADD,
|
||||
ADD_STRONG,
|
||||
STRING_ADD_LEFT,
|
||||
STRING_ADD_RIGHT,
|
||||
SUB,
|
||||
SUB_STRONG,
|
||||
MUL,
|
||||
MUL_STRONG,
|
||||
DIV,
|
||||
DIV_STRONG,
|
||||
MOD,
|
||||
MOD_STRONG,
|
||||
BIT_OR,
|
||||
BIT_OR_STRONG,
|
||||
BIT_AND,
|
||||
BIT_AND_STRONG,
|
||||
BIT_XOR,
|
||||
BIT_XOR_STRONG,
|
||||
SHL,
|
||||
SHL_STRONG,
|
||||
SAR,
|
||||
SAR_STRONG,
|
||||
SHR,
|
||||
SHR_STRONG,
|
||||
IN,
|
||||
CALL_NON_FUNCTION,
|
||||
CALL_NON_FUNCTION_AS_CONSTRUCTOR,
|
||||
CALL_FUNCTION_PROXY,
|
||||
CALL_FUNCTION_PROXY_AS_CONSTRUCTOR,
|
||||
CONCAT_ITERABLE_TO_ARRAY,
|
||||
APPLY_PREPARE,
|
||||
REFLECT_APPLY_PREPARE,
|
||||
REFLECT_CONSTRUCT_PREPARE,
|
||||
STACK_OVERFLOW,
|
||||
TO_NUMBER,
|
||||
TO_STRING,
|
||||
TO_NAME,
|
||||
});
|
||||
%InstallToContext([
|
||||
"add_builtin", ADD,
|
||||
"add_strong_builtin", ADD_STRONG,
|
||||
"apply_prepare_builtin", APPLY_PREPARE,
|
||||
"bit_and_builtin", BIT_AND,
|
||||
"bit_and_strong_builtin", BIT_AND_STRONG,
|
||||
"bit_or_builtin", BIT_OR,
|
||||
"bit_or_strong_builtin", BIT_OR_STRONG,
|
||||
"bit_xor_builtin", BIT_XOR,
|
||||
"bit_xor_strong_builtin", BIT_XOR_STRONG,
|
||||
"call_function_proxy_as_constructor_builtin", CALL_FUNCTION_PROXY_AS_CONSTRUCTOR,
|
||||
"call_function_proxy_builtin", CALL_FUNCTION_PROXY,
|
||||
"call_non_function_as_constructor_builtin", CALL_NON_FUNCTION_AS_CONSTRUCTOR,
|
||||
"call_non_function_builtin", CALL_NON_FUNCTION,
|
||||
"compare_builtin", COMPARE,
|
||||
"compare_strong_builtin", COMPARE_STRONG,
|
||||
"concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY,
|
||||
"div_builtin", DIV,
|
||||
"div_strong_builtin", DIV_STRONG,
|
||||
"equals_builtin", EQUALS,
|
||||
"in_builtin", IN,
|
||||
"mod_builtin", MOD,
|
||||
"mod_strong_builtin", MOD_STRONG,
|
||||
"mul_builtin", MUL,
|
||||
"mul_strong_builtin", MUL_STRONG,
|
||||
"reflect_apply_prepare_builtin", REFLECT_APPLY_PREPARE,
|
||||
"reflect_construct_prepare_builtin", REFLECT_CONSTRUCT_PREPARE,
|
||||
"sar_builtin", SAR,
|
||||
"sar_strong_builtin", SAR_STRONG,
|
||||
"shl_builtin", SHL,
|
||||
"shl_strong_builtin", SHL_STRONG,
|
||||
"shr_builtin", SHR,
|
||||
"shr_strong_builtin", SHR_STRONG,
|
||||
"stack_overflow_builtin", STACK_OVERFLOW,
|
||||
"string_add_left_builtin", STRING_ADD_LEFT,
|
||||
"string_add_right_builtin", STRING_ADD_RIGHT,
|
||||
"sub_builtin", SUB,
|
||||
"sub_strong_builtin", SUB_STRONG,
|
||||
"to_name_builtin", TO_NAME,
|
||||
"to_number_builtin", TO_NUMBER,
|
||||
"to_string_builtin", TO_STRING,
|
||||
]);
|
||||
|
||||
%InstallToContext([
|
||||
"concat_iterable_to_array", ConcatIterableToArray,
|
||||
|
@ -62,16 +62,6 @@ RUNTIME_FUNCTION(Runtime_InstallToContext) {
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_InstallJSBuiltins) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, container, 0);
|
||||
RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
|
||||
Bootstrapper::InstallJSBuiltins(isolate, container);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_Throw) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 1);
|
||||
|
@ -304,7 +304,6 @@ namespace internal {
|
||||
F(CheckIsBootstrapping, 0, 1) \
|
||||
F(ExportPrivateSymbols, 1, 1) \
|
||||
F(InstallToContext, 1, 1) \
|
||||
F(InstallJSBuiltins, 1, 1) \
|
||||
F(Throw, 1, 1) \
|
||||
F(ReThrow, 1, 1) \
|
||||
F(UnwindAndFindExceptionHandler, 0, 1) \
|
||||
|
@ -525,7 +525,7 @@ static void Generate_CheckStackOverflow(MacroAssembler* masm,
|
||||
__ Integer32ToSmi(rax, rax);
|
||||
}
|
||||
__ Push(rax);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
|
||||
__ bind(&okay);
|
||||
}
|
||||
@ -718,7 +718,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ subp(rdx, rcx);
|
||||
__ CompareRoot(rdx, Heap::kRealStackLimitRootIndex);
|
||||
__ j(above_equal, &ok, Label::kNear);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
|
||||
// If ok, push undefined as the initial value for all register file entries.
|
||||
@ -1136,12 +1136,12 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
__ Push(rdi); // re-add proxy object as additional argument
|
||||
__ PushReturnAddressFrom(rdx);
|
||||
__ incp(rax);
|
||||
__ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinEntry(rdx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&non_proxy);
|
||||
__ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinEntry(rdx, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ bind(&function);
|
||||
@ -1238,9 +1238,10 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ Push(Operand(rbp, kFunctionOffset));
|
||||
__ Push(Operand(rbp, kArgumentsOffset));
|
||||
if (targetIsArgument) {
|
||||
__ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged);
|
||||
@ -1326,7 +1327,7 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ Push(rdi); // add function proxy as last argument
|
||||
__ incp(rax);
|
||||
__ Set(rbx, 0);
|
||||
__ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinEntry(rdx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
@ -1371,7 +1372,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
|
||||
__ Push(Operand(rbp, kFunctionOffset));
|
||||
__ Push(Operand(rbp, kArgumentsOffset));
|
||||
__ Push(Operand(rbp, kNewTargetOffset));
|
||||
__ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged);
|
||||
|
||||
@ -1578,7 +1580,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(rdi); // Preserve the function.
|
||||
__ Push(rax);
|
||||
__ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_STRING_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ Pop(rdi);
|
||||
}
|
||||
__ movp(rbx, rax);
|
||||
@ -1792,7 +1794,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ int3();
|
||||
}
|
||||
}
|
||||
|
@ -1765,12 +1765,13 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
__ PushReturnAddressFrom(rcx);
|
||||
__ TailCallRuntime(Runtime::kStrictEquals, 2, 1);
|
||||
} else {
|
||||
Builtins::JavaScript builtin;
|
||||
int context_index;
|
||||
if (cc == equal) {
|
||||
builtin = Builtins::EQUALS;
|
||||
context_index = Context::EQUALS_BUILTIN_INDEX;
|
||||
} else {
|
||||
builtin =
|
||||
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||
context_index = is_strong(strength())
|
||||
? Context::COMPARE_STRONG_BUILTIN_INDEX
|
||||
: Context::COMPARE_BUILTIN_INDEX;
|
||||
__ Push(Smi::FromInt(NegativeComparisonResult(cc)));
|
||||
}
|
||||
|
||||
@ -1778,7 +1779,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
|
||||
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
|
||||
// tagged as a small integer.
|
||||
__ InvokeBuiltin(builtin, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(context_index, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
__ bind(&miss);
|
||||
@ -1941,7 +1942,7 @@ static void EmitSlowCase(Isolate* isolate,
|
||||
__ PushReturnAddressFrom(rcx);
|
||||
__ Set(rax, argc + 1);
|
||||
__ Set(rbx, 0);
|
||||
__ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinEntry(rdx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
{
|
||||
Handle<Code> adaptor =
|
||||
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
|
||||
@ -1954,7 +1955,7 @@ static void EmitSlowCase(Isolate* isolate,
|
||||
__ movp(args->GetReceiverOperand(), rdi);
|
||||
__ Set(rax, argc);
|
||||
__ Set(rbx, 0);
|
||||
__ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinEntry(rdx, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
Handle<Code> adaptor =
|
||||
isolate->builtins()->ArgumentsAdaptorTrampoline();
|
||||
__ Jump(adaptor, RelocInfo::CODE_TARGET);
|
||||
@ -2098,11 +2099,13 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(&slow);
|
||||
__ CmpInstanceType(r11, JS_FUNCTION_PROXY_TYPE);
|
||||
__ j(not_equal, &non_function_call);
|
||||
__ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinEntry(rdx,
|
||||
Context::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ jmp(&do_call);
|
||||
|
||||
__ bind(&non_function_call);
|
||||
__ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinEntry(rdx,
|
||||
Context::CALL_NON_FUNCTION_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ bind(&do_call);
|
||||
// Set expected number of arguments to zero (not changing rax).
|
||||
__ Set(rbx, 0);
|
||||
@ -3221,7 +3224,7 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
|
||||
__ PopReturnAddressTo(rcx); // Pop return address.
|
||||
__ Push(rax); // Push argument.
|
||||
__ PushReturnAddressFrom(rcx); // Push return address.
|
||||
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_NUMBER_BUILTIN_INDEX, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
|
@ -698,8 +698,7 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& ext,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper) {
|
||||
// You can't call a builtin without a valid frame.
|
||||
DCHECK(flag == JUMP_FUNCTION || has_frame());
|
||||
@ -708,25 +707,25 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
// arguments match the expected number of arguments. Fake a
|
||||
// parameter count to avoid emitting code to do the check.
|
||||
ParameterCount expected(0);
|
||||
GetBuiltinEntry(rdx, id);
|
||||
GetBuiltinEntry(rdx, native_context_index);
|
||||
InvokeCode(rdx, expected, expected, flag, call_wrapper);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinFunction(Register target,
|
||||
Builtins::JavaScript id) {
|
||||
int native_context_index) {
|
||||
// Load the builtins object into target register.
|
||||
movp(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
||||
movp(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
|
||||
movp(target, FieldOperand(target,
|
||||
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
|
||||
movp(target, FieldOperand(target, GlobalObject::kNativeContextOffset));
|
||||
movp(target, ContextOperand(target, native_context_index));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
|
||||
void MacroAssembler::GetBuiltinEntry(Register target,
|
||||
int native_context_index) {
|
||||
DCHECK(!target.is(rdi));
|
||||
// Load the JavaScript builtin function from the builtins object.
|
||||
GetBuiltinFunction(rdi, id);
|
||||
GetBuiltinFunction(rdi, native_context_index);
|
||||
movp(target, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
|
||||
}
|
||||
|
||||
|
@ -375,17 +375,15 @@ class MacroAssembler: public Assembler {
|
||||
InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper);
|
||||
|
||||
// Invoke specified builtin JavaScript function. Adds an entry to
|
||||
// the unresolved list if the name does not resolve.
|
||||
void InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
// Invoke specified builtin JavaScript function.
|
||||
void InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper = NullCallWrapper());
|
||||
|
||||
// Store the function for the given builtin in the target register.
|
||||
void GetBuiltinFunction(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinFunction(Register target, int native_context_index);
|
||||
|
||||
// Store the code object for the given builtin in the target register.
|
||||
void GetBuiltinEntry(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinEntry(Register target, int native_context_index);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -522,7 +522,7 @@ static void Generate_CheckStackOverflow(MacroAssembler* masm,
|
||||
__ SmiTag(eax);
|
||||
}
|
||||
__ push(eax);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
|
||||
__ bind(&okay);
|
||||
}
|
||||
@ -660,7 +660,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
ExternalReference::address_of_real_stack_limit(masm->isolate());
|
||||
__ cmp(ecx, Operand::StaticVariable(stack_limit));
|
||||
__ j(above_equal, &ok);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ bind(&ok);
|
||||
|
||||
// If ok, push undefined as the initial value for all register file entries.
|
||||
@ -1081,12 +1081,12 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
|
||||
__ push(edi); // re-add proxy object as additional argument
|
||||
__ push(edx);
|
||||
__ inc(eax);
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinEntry(edx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&non_proxy);
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinEntry(edx, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
__ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ bind(&function);
|
||||
@ -1183,9 +1183,10 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ push(Operand(ebp, kFunctionOffset)); // push this
|
||||
__ push(Operand(ebp, kArgumentsOffset)); // push arguments
|
||||
if (targetIsArgument) {
|
||||
__ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
} else {
|
||||
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
}
|
||||
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged);
|
||||
@ -1272,7 +1273,7 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
|
||||
__ push(edi); // add function proxy as last argument
|
||||
__ inc(eax);
|
||||
__ Move(ebx, Immediate(0));
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinEntry(edx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
__ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
@ -1317,7 +1318,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
|
||||
__ push(Operand(ebp, kFunctionOffset));
|
||||
__ push(Operand(ebp, kArgumentsOffset));
|
||||
__ push(Operand(ebp, kNewTargetOffset));
|
||||
__ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
|
||||
CALL_FUNCTION);
|
||||
|
||||
Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged);
|
||||
|
||||
@ -1521,7 +1523,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ push(edi); // Preserve the function.
|
||||
__ push(eax);
|
||||
__ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_STRING_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ pop(edi);
|
||||
}
|
||||
__ mov(ebx, eax);
|
||||
@ -1723,7 +1725,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
|
||||
__ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION);
|
||||
__ int3();
|
||||
}
|
||||
}
|
||||
|
@ -1603,12 +1603,13 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
__ push(ecx);
|
||||
__ TailCallRuntime(Runtime::kStrictEquals, 2, 1);
|
||||
} else {
|
||||
Builtins::JavaScript builtin;
|
||||
int context_index;
|
||||
if (cc == equal) {
|
||||
builtin = Builtins::EQUALS;
|
||||
context_index = Context::EQUALS_BUILTIN_INDEX;
|
||||
} else {
|
||||
builtin =
|
||||
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||
context_index = is_strong(strength())
|
||||
? Context::COMPARE_STRONG_BUILTIN_INDEX
|
||||
: Context::COMPARE_BUILTIN_INDEX;
|
||||
__ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
|
||||
}
|
||||
|
||||
@ -1617,7 +1618,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
||||
|
||||
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
|
||||
// tagged as a small integer.
|
||||
__ InvokeBuiltin(builtin, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(context_index, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
__ bind(&miss);
|
||||
@ -1782,7 +1783,7 @@ static void EmitSlowCase(Isolate* isolate,
|
||||
__ push(ecx);
|
||||
__ Move(eax, Immediate(argc + 1));
|
||||
__ Move(ebx, Immediate(0));
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
|
||||
__ GetBuiltinEntry(edx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
|
||||
{
|
||||
Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
|
||||
__ jmp(adaptor, RelocInfo::CODE_TARGET);
|
||||
@ -1794,7 +1795,7 @@ static void EmitSlowCase(Isolate* isolate,
|
||||
__ mov(Operand(esp, (argc + 1) * kPointerSize), edi);
|
||||
__ Move(eax, Immediate(argc));
|
||||
__ Move(ebx, Immediate(0));
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
|
||||
__ GetBuiltinEntry(edx, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
|
||||
Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
|
||||
__ jmp(adaptor, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
@ -1938,11 +1939,13 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(&slow);
|
||||
__ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
|
||||
__ j(not_equal, &non_function_call);
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinEntry(edx,
|
||||
Context::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ jmp(&do_call);
|
||||
|
||||
__ bind(&non_function_call);
|
||||
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
|
||||
__ GetBuiltinEntry(edx,
|
||||
Context::CALL_NON_FUNCTION_AS_CONSTRUCTOR_BUILTIN_INDEX);
|
||||
__ bind(&do_call);
|
||||
if (IsSuperConstructorCall()) {
|
||||
__ Drop(1);
|
||||
@ -2978,7 +2981,7 @@ void ToNumberStub::Generate(MacroAssembler* masm) {
|
||||
__ pop(ecx); // Pop return address.
|
||||
__ push(eax); // Push argument.
|
||||
__ push(ecx); // Push return address.
|
||||
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
|
||||
__ InvokeBuiltin(Context::TO_NUMBER_BUILTIN_INDEX, JUMP_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2021,8 +2021,7 @@ void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper) {
|
||||
// You can't call a builtin without a valid frame.
|
||||
DCHECK(flag == JUMP_FUNCTION || has_frame());
|
||||
@ -2031,26 +2030,26 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
||||
// arguments match the expected number of arguments. Fake a
|
||||
// parameter count to avoid emitting code to do the check.
|
||||
ParameterCount expected(0);
|
||||
GetBuiltinFunction(edi, id);
|
||||
GetBuiltinFunction(edi, native_context_index);
|
||||
InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
|
||||
expected, expected, flag, call_wrapper);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinFunction(Register target,
|
||||
Builtins::JavaScript id) {
|
||||
int native_context_index) {
|
||||
// Load the JavaScript builtin function from the builtins object.
|
||||
mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
||||
mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
|
||||
mov(target, FieldOperand(target,
|
||||
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
|
||||
mov(target, FieldOperand(target, GlobalObject::kNativeContextOffset));
|
||||
mov(target, ContextOperand(target, native_context_index));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
|
||||
void MacroAssembler::GetBuiltinEntry(Register target,
|
||||
int native_context_index) {
|
||||
DCHECK(!target.is(edi));
|
||||
// Load the JavaScript builtin function from the builtins object.
|
||||
GetBuiltinFunction(edi, id);
|
||||
GetBuiltinFunction(edi, native_context_index);
|
||||
// Load the code entry point from the function into the target register.
|
||||
mov(target, FieldOperand(edi, JSFunction::kCodeEntryOffset));
|
||||
}
|
||||
|
@ -330,17 +330,15 @@ class MacroAssembler: public Assembler {
|
||||
InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper);
|
||||
|
||||
// Invoke specified builtin JavaScript function. Adds an entry to
|
||||
// the unresolved list if the name does not resolve.
|
||||
void InvokeBuiltin(Builtins::JavaScript id,
|
||||
InvokeFlag flag,
|
||||
// Invoke specified builtin JavaScript function.
|
||||
void InvokeBuiltin(int native_context_index, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper = NullCallWrapper());
|
||||
|
||||
// Store the function for the given builtin in the target register.
|
||||
void GetBuiltinFunction(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinFunction(Register target, int native_context_index);
|
||||
|
||||
// Store the code object for the given builtin in the target register.
|
||||
void GetBuiltinEntry(Register target, Builtins::JavaScript id);
|
||||
void GetBuiltinEntry(Register target, int native_context_index);
|
||||
|
||||
// Expression support
|
||||
// Support for constant splitting.
|
||||
|
@ -269,11 +269,18 @@ TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) {
|
||||
TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) {
|
||||
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
|
||||
InterpreterAssemblerForTest m(this, bytecode);
|
||||
Node* load_context = m.LoadContextSlot(22);
|
||||
EXPECT_THAT(load_context,
|
||||
m.IsLoad(kMachAnyTagged,
|
||||
IsParameter(Linkage::kInterpreterContextParameter),
|
||||
IsIntPtrConstant(Context::SlotOffset(22))));
|
||||
Node* load_from_current_context = m.LoadContextSlot(22);
|
||||
Matcher<Node*> load_from_current_context_matcher = m.IsLoad(
|
||||
kMachAnyTagged, IsParameter(Linkage::kInterpreterContextParameter),
|
||||
IsIntPtrConstant(Context::SlotOffset(22)));
|
||||
EXPECT_THAT(load_from_current_context, load_from_current_context_matcher);
|
||||
|
||||
// Let's imagine that the loaded context slot is another context.
|
||||
Node* load_from_any_context =
|
||||
m.LoadContextSlot(load_from_current_context, 23);
|
||||
EXPECT_THAT(load_from_any_context,
|
||||
m.IsLoad(kMachAnyTagged, load_from_current_context_matcher,
|
||||
IsIntPtrConstant(Context::SlotOffset(23))));
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,19 +302,18 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallJSBuiltin) {
|
||||
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
|
||||
InterpreterAssemblerForTest m(this, bytecode);
|
||||
Node* receiver = m.IntPtrConstant(1234);
|
||||
Node* call_js_builtin_0 = m.CallJSBuiltin(Builtins::SUB, receiver);
|
||||
Node* call_js_builtin_0 =
|
||||
m.CallJSBuiltin(Context::SUB_BUILTIN_INDEX, receiver);
|
||||
|
||||
Matcher<Node*> load_globals_matcher = m.IsLoad(
|
||||
kMachAnyTagged, IsParameter(Linkage::kInterpreterContextParameter),
|
||||
IsIntPtrConstant(Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
||||
Matcher<Node*> load_builtins_matcher = m.IsLoad(
|
||||
Matcher<Node*> load_native_context_matcher = m.IsLoad(
|
||||
kMachAnyTagged, load_globals_matcher,
|
||||
IsIntPtrConstant(GlobalObject::kBuiltinsOffset - kHeapObjectTag));
|
||||
Matcher<Node*> function_matcher =
|
||||
m.IsLoad(kMachAnyTagged, load_builtins_matcher,
|
||||
IsIntPtrConstant(
|
||||
JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::SUB) -
|
||||
kHeapObjectTag));
|
||||
IsIntPtrConstant(GlobalObject::kNativeContextOffset - kHeapObjectTag));
|
||||
Matcher<Node*> function_matcher = m.IsLoad(
|
||||
kMachAnyTagged, load_native_context_matcher,
|
||||
IsIntPtrConstant(Context::SlotOffset(Context::SUB_BUILTIN_INDEX)));
|
||||
Matcher<Node*> context_matcher =
|
||||
m.IsLoad(kMachAnyTagged, function_matcher,
|
||||
IsIntPtrConstant(JSFunction::kContextOffset - kHeapObjectTag));
|
||||
@ -316,7 +322,8 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallJSBuiltin) {
|
||||
m.graph()->start(), m.graph()->start()));
|
||||
|
||||
Node* arg1 = m.Int32Constant(0xabcd);
|
||||
Node* call_js_builtin_1 = m.CallJSBuiltin(Builtins::SUB, receiver, arg1);
|
||||
Node* call_js_builtin_1 =
|
||||
m.CallJSBuiltin(Context::SUB_BUILTIN_INDEX, receiver, arg1);
|
||||
EXPECT_THAT(call_js_builtin_1,
|
||||
IsCall(_, function_matcher, receiver, arg1, context_matcher,
|
||||
m.graph()->start(), m.graph()->start()));
|
||||
|
Loading…
Reference in New Issue
Block a user