Revert of [Interpreter] Support for operator new. (patchset #17 id:290001 of https://codereview.chromium.org/1402943002/ )

Reason for revert:
[Sheriff] Breaks arm64 debug:
http://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20arm64%20-%20sim%20-%20debug/builds/4595

Original issue's description:
> [Interpreter] Support for operator new.
>
> This change add a new bytecode for operator new and implements it using
> the Construct() builtin.
>
> BUG=v8:4280
> LOG=N
>
> Committed: https://crrev.com/8e4f9963d53913eab7fbd2f61a5733d8dc2169e7
> Cr-Commit-Position: refs/heads/master@{#31293}

TBR=rmcilroy@chromium.org,bmeurer@chromium.org,oth@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:4280

Review URL: https://codereview.chromium.org/1402153004

Cr-Commit-Position: refs/heads/master@{#31298}
This commit is contained in:
machenbach 2015-10-15 05:49:57 -07:00 committed by Commit bot
parent f4c9f2221b
commit 0937cdbfbd
30 changed files with 52 additions and 628 deletions

View File

@ -976,19 +976,6 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
} }
static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index,
Register limit, Register scratch) {
Label loop_header, loop_check;
__ b(al, &loop_check);
__ bind(&loop_header);
__ ldr(scratch, MemOperand(index, -kPointerSize, PostIndex));
__ push(scratch);
__ bind(&loop_check);
__ cmp(index, limit);
__ b(gt, &loop_header);
}
// static // static
void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) { void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
@ -997,40 +984,27 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
// arguments should be consecutive above this, in the same order as // arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack. // they are to be pushed onto the stack.
// -- r1 : the target to call (can be any Object). // -- r1 : the target to call (can be any Object).
// -----------------------------------
// Find the address of the last argument. // Find the address of the last argument.
__ add(r3, r0, Operand(1)); // Add one for receiver. __ add(r3, r0, Operand(1)); // Add one for receiver.
__ mov(r3, Operand(r3, LSL, kPointerSizeLog2)); __ mov(r3, Operand(r3, LSL, kPointerSizeLog2));
__ sub(r3, r2, r3); __ sub(r3, r2, r3);
Generate_InterpreterPushArgs(masm, r2, r3, r4); // Push the arguments.
Label loop_header, loop_check;
__ b(al, &loop_check);
__ bind(&loop_header);
__ ldr(r4, MemOperand(r2, -kPointerSize, PostIndex));
__ push(r4);
__ bind(&loop_check);
__ cmp(r2, r3);
__ b(gt, &loop_header);
// Call the target. // Call the target.
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
} }
// static
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : argument count (not including receiver)
// -- r3 : original constructor
// -- r1 : constructor to call
// -- r2 : address of the first argument
// -----------------------------------
// Find the address of the last argument.
__ mov(r4, Operand(r0, LSL, kPointerSizeLog2));
__ sub(r4, r2, r4);
Generate_InterpreterPushArgs(masm, r2, r4, r5);
// Call the constructor with r0, r1, and r3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
}
void Builtins::Generate_CompileLazy(MacroAssembler* masm) { void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
CallRuntimePassFunction(masm, Runtime::kCompileLazy); CallRuntimePassFunction(masm, Runtime::kCompileLazy);
GenerateTailCallToReturnedCode(masm); GenerateTailCallToReturnedCode(masm);

View File

@ -420,18 +420,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
r0, // argument count (not including receiver)
r3, // original constructor
r1, // constructor to call
r2 // address of the first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {

View File

@ -1769,7 +1769,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
// arguments should be consecutive above this, in the same order as // arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack. // they are to be pushed onto the stack.
// -- x1 : the target to call (can be any Object). // -- x1 : the target to call (can be any Object).
// -----------------------------------
// Find the address of the last argument. // Find the address of the last argument.
__ add(x3, x0, Operand(1)); // Add one for receiver. __ add(x3, x0, Operand(1)); // Add one for receiver.
@ -1794,37 +1793,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
} }
// static
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- x0 : argument count (not including receiver)
// -- x3 : original constructor
// -- x1 : constructor to call
// -- x2 : address of the first argument
// -----------------------------------
// Find the address of the last argument.
__ lsl(x5, x0, kPointerSizeLog2);
__ sub(x4, x2, x5);
// Push the arguments.
Label loop_header, loop_check;
__ Mov(x6, jssp);
__ Claim(x5, 1);
__ B(&loop_check);
__ Bind(&loop_header);
// TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned.
__ Ldr(x5, MemOperand(x2, -kPointerSize, PostIndex));
__ Str(x5, MemOperand(x6, -kPointerSize, PreIndex));
__ Bind(&loop_check);
__ Cmp(x2, x4);
__ B(gt, &loop_header);
// Call the constructor with x0, x1, and x3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
}
void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline"); ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline");
// ----------- S t a t e ------------- // ----------- S t a t e -------------

View File

@ -449,18 +449,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
x0, // argument count (not including receiver)
x3, // original constructor
x1, // constructor to call
x2 // address of the first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {

View File

@ -104,7 +104,6 @@ enum BuiltinExtraArguments {
V(InterpreterEntryTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(InterpreterEntryTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(InterpreterExitTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(InterpreterExitTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(InterpreterPushArgsAndCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(InterpreterPushArgsAndCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(InterpreterPushArgsAndConstruct, BUILTIN, UNINITIALIZED, kNoExtraICState) \
\ \
V(LoadIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(LoadIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(KeyedLoadIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(KeyedLoadIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \
@ -309,7 +308,6 @@ class Builtins {
static void Generate_InterpreterEntryTrampoline(MacroAssembler* masm); static void Generate_InterpreterEntryTrampoline(MacroAssembler* masm);
static void Generate_InterpreterExitTrampoline(MacroAssembler* masm); static void Generate_InterpreterExitTrampoline(MacroAssembler* masm);
static void Generate_InterpreterPushArgsAndCall(MacroAssembler* masm); static void Generate_InterpreterPushArgsAndCall(MacroAssembler* masm);
static void Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm);
#define DECLARE_CODE_AGE_BUILTIN_GENERATOR(C) \ #define DECLARE_CODE_AGE_BUILTIN_GENERATOR(C) \
static void Generate_Make##C##CodeYoungAgainEvenMarking( \ static void Generate_Make##C##CodeYoungAgainEvenMarking( \

View File

@ -275,13 +275,6 @@ Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate) {
} }
// static
Callable CodeFactory::InterpreterPushArgsAndConstruct(Isolate* isolate) {
return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(),
InterpreterPushArgsAndConstructDescriptor(isolate));
}
// static // static
Callable CodeFactory::InterpreterCEntry(Isolate* isolate) { Callable CodeFactory::InterpreterCEntry(Isolate* isolate) {
// TODO(rmcilroy): Deal with runtime functions that return two values. // TODO(rmcilroy): Deal with runtime functions that return two values.

View File

@ -98,7 +98,6 @@ class CodeFactory final {
CallFunctionFlags flags); CallFunctionFlags flags);
static Callable InterpreterPushArgsAndCall(Isolate* isolate); static Callable InterpreterPushArgsAndCall(Isolate* isolate);
static Callable InterpreterPushArgsAndConstruct(Isolate* isolate);
static Callable InterpreterCEntry(Isolate* isolate); static Callable InterpreterCEntry(Isolate* isolate);
}; };

View File

@ -357,12 +357,6 @@ void BytecodeGraphBuilder::VisitCallRuntime(
} }
void BytecodeGraphBuilder::VisitNew(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::BuildBinaryOp( void BytecodeGraphBuilder::BuildBinaryOp(
const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0)); Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0));

View File

@ -317,26 +317,6 @@ Node* InterpreterAssembler::LoadTypeFeedbackVector() {
} }
Node* InterpreterAssembler::CallConstruct(Node* original_constructor,
Node* constructor, Node* first_arg,
Node* arg_count) {
Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(isolate());
CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags);
Node* code_target = HeapConstant(callable.code());
Node** args = zone()->NewArray<Node*>(5);
args[0] = arg_count;
args[1] = original_constructor;
args[2] = constructor;
args[3] = first_arg;
args[4] = GetContext();
return CallN(descriptor, code_target, args);
}
Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target, Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target,
Node** args) { Node** args) {
Node* stack_pointer_before_call = nullptr; Node* stack_pointer_before_call = nullptr;

View File

@ -101,17 +101,8 @@ class InterpreterAssembler {
// Load the TypeFeedbackVector for the current function. // Load the TypeFeedbackVector for the current function.
Node* LoadTypeFeedbackVector(); Node* LoadTypeFeedbackVector();
// Call constructor |constructor| with |arg_count| arguments (not // Call JSFunction or Callable |function| with |arg_count| (not including
// including receiver) and the first argument located at // receiver) and the first argument located at |first_arg|.
// |first_arg|. The |original_constructor| is the same as the
// |constructor| for the new keyword, but differs for the super
// keyword.
Node* CallConstruct(Node* original_constructor, Node* constructor,
Node* first_arg, Node* arg_count);
// Call JSFunction or Callable |function| with |arg_count|
// arguments (not including receiver) and the first argument
// located at |first_arg|.
Node* CallJS(Node* function, Node* first_arg, Node* arg_count); Node* CallJS(Node* function, Node* first_arg, Node* arg_count);
// Call an IC code stub. // Call an IC code stub.

View File

@ -724,24 +724,6 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
} }
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
Register array_limit) {
// ----------- S t a t e -------------
// -- ebx : Pointer to the last argument in the args array.
// -- array_limit : Pointer to one before the first argument in the
// args array.
// -----------------------------------
Label loop_header, loop_check;
__ jmp(&loop_check);
__ bind(&loop_header);
__ Push(Operand(ebx, 0));
__ sub(ebx, Immediate(kPointerSize));
__ bind(&loop_check);
__ cmp(ebx, array_limit);
__ j(greater, &loop_header, Label::kNear);
}
// static // static
void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) { void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
@ -750,7 +732,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
// arguments should be consecutive above this, in the same order as // arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack. // they are to be pushed onto the stack.
// -- edi : the target to call (can be any Object). // -- edi : the target to call (can be any Object).
// -----------------------------------
// Pop return address to allow tail-call after pushing arguments. // Pop return address to allow tail-call after pushing arguments.
__ Pop(edx); __ Pop(edx);
@ -762,7 +743,15 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
__ neg(ecx); __ neg(ecx);
__ add(ecx, ebx); __ add(ecx, ebx);
Generate_InterpreterPushArgs(masm, ecx); // Push the arguments.
Label loop_header, loop_check;
__ jmp(&loop_check);
__ bind(&loop_header);
__ Push(Operand(ebx, 0));
__ sub(ebx, Immediate(kPointerSize));
__ bind(&loop_check);
__ cmp(ebx, ecx);
__ j(greater, &loop_header, Label::kNear);
// Call the target. // Call the target.
__ Push(edx); // Re-push return address. __ Push(edx); // Re-push return address.
@ -770,53 +759,13 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
} }
// static
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : the number of arguments (not including the receiver)
// -- edx : the original constructor
// -- edi : the constructor
// -- ebx : the address of the first argument to be pushed. Subsequent
// arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack.
// -----------------------------------
// Save number of arguments on the stack below where arguments are going
// to be pushed.
__ mov(ecx, eax);
__ neg(ecx);
__ mov(Operand(esp, ecx, times_pointer_size, -kPointerSize), eax);
__ mov(eax, ecx);
// Pop return address to allow tail-call after pushing arguments.
__ Pop(ecx);
// Find the address of the last argument.
__ shl(eax, kPointerSizeLog2);
__ add(eax, ebx);
// Push padding for receiver.
__ Push(Immediate(0));
Generate_InterpreterPushArgs(masm, eax);
// Restore number of arguments from slot on stack.
__ mov(eax, Operand(esp, -kPointerSize));
// Re-push return address.
__ Push(ecx);
// Call the constructor with unmodified eax, edi, ebi values.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
}
void Builtins::Generate_CompileLazy(MacroAssembler* masm) { void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
CallRuntimePassFunction(masm, Runtime::kCompileLazy); CallRuntimePassFunction(masm, Runtime::kCompileLazy);
GenerateTailCallToReturnedCode(masm); GenerateTailCallToReturnedCode(masm);
} }
static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) { static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) {
FrameScope scope(masm, StackFrame::INTERNAL); FrameScope scope(masm, StackFrame::INTERNAL);
// Push a copy of the function. // Push a copy of the function.

View File

@ -401,18 +401,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
eax, // argument count (not including receiver)
edx, // original constructor
edi, // constructor
ebx, // address of first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {

View File

@ -71,7 +71,6 @@ class PlatformInterfaceDescriptor;
V(MathRoundVariantCallFromUnoptimizedCode) \ V(MathRoundVariantCallFromUnoptimizedCode) \
V(MathRoundVariantCallFromOptimizedCode) \ V(MathRoundVariantCallFromOptimizedCode) \
V(InterpreterPushArgsAndCall) \ V(InterpreterPushArgsAndCall) \
V(InterpreterPushArgsAndConstruct) \
V(InterpreterCEntry) V(InterpreterCEntry)
@ -717,14 +716,6 @@ class InterpreterPushArgsAndCallDescriptor : public CallInterfaceDescriptor {
}; };
class InterpreterPushArgsAndConstructDescriptor
: public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR(InterpreterPushArgsAndConstructDescriptor,
CallInterfaceDescriptor)
};
class InterpreterCEntryDescriptor : public CallInterfaceDescriptor { class InterpreterCEntryDescriptor : public CallInterfaceDescriptor {
public: public:
DECLARE_DESCRIPTOR(InterpreterCEntryDescriptor, CallInterfaceDescriptor) DECLARE_DESCRIPTOR(InterpreterCEntryDescriptor, CallInterfaceDescriptor)

View File

@ -599,16 +599,6 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
} }
BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
Register first_arg,
size_t arg_count) {
DCHECK(FitsInIdx8Operand(arg_count));
Output(Bytecode::kNew, constructor.ToOperand(), first_arg.ToOperand(),
static_cast<uint8_t>(arg_count));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { Runtime::FunctionId function_id, Register first_arg, size_t arg_count) {
DCHECK(FitsInIdx16Operand(function_id)); DCHECK(FitsInIdx16Operand(function_id));

View File

@ -100,19 +100,13 @@ class BytecodeArrayBuilder {
BytecodeArrayBuilder& Call(Register callable, Register receiver, BytecodeArrayBuilder& Call(Register callable, Register receiver,
size_t arg_count); size_t arg_count);
// Call the new operator. The |constructor| register is followed by
// |arg_count| consecutive registers containing arguments to be
// applied to the constructor.
BytecodeArrayBuilder& New(Register constructor, Register first_arg,
size_t arg_count);
// Call the runtime function with |function_id|. The first argument should be // Call the runtime function with |function_id|. The first argument should be
// in |first_arg| and all subsequent arguments should be in registers // in |first_arg| and all subsequent arguments should be in registers
// <first_arg + 1> to <first_arg + 1 + arg_count>. // <first_arg + 1> to <first_arg + 1 + arg_count>.
BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id, BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id,
Register first_arg, size_t arg_count); Register first_arg, size_t arg_count);
// Operators (register holds the lhs value, accumulator holds the rhs value). // Operators (register == lhs, accumulator = rhs).
BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg, BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg,
Strength strength); Strength strength);

View File

@ -934,25 +934,6 @@ void BytecodeGenerator::VisitProperty(Property* expr) {
} }
Register BytecodeGenerator::VisitArguments(
ZoneList<Expression*>* args, TemporaryRegisterScope* register_scope) {
// Visit arguments and place in a contiguous block of temporary registers.
// Return the first temporary register corresponding to the first argument.
DCHECK_GT(args->length(), 0);
Register first_arg = register_scope->NewRegister();
Visit(args->at(0));
builder()->StoreAccumulatorInRegister(first_arg);
for (int i = 1; i < static_cast<int>(args->length()); i++) {
Register ith_arg = register_scope->NewRegister();
Visit(args->at(i));
builder()->StoreAccumulatorInRegister(ith_arg);
DCHECK(ith_arg.index() - i == first_arg.index());
}
return first_arg;
}
void BytecodeGenerator::VisitCall(Call* expr) { void BytecodeGenerator::VisitCall(Call* expr) {
Expression* callee_expr = expr->expression(); Expression* callee_expr = expr->expression();
Call::CallType call_type = expr->GetCallType(isolate()); Call::CallType call_type = expr->GetCallType(isolate());
@ -1000,9 +981,11 @@ void BytecodeGenerator::VisitCall(Call* expr) {
// Evaluate all arguments to the function call and store in sequential // Evaluate all arguments to the function call and store in sequential
// registers. // registers.
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
if (args->length() > 0) { for (int i = 0; i < args->length(); ++i) {
Register first_arg = VisitArguments(args, &temporary_register_scope); Visit(args->at(i));
CHECK_EQ(first_arg.index(), receiver.index() + 1); Register arg = temporary_register_scope.NewRegister();
DCHECK(arg.index() - i == receiver.index() + 1);
builder()->StoreAccumulatorInRegister(arg);
} }
// TODO(rmcilroy): Deal with possible direct eval here? // TODO(rmcilroy): Deal with possible direct eval here?
@ -1011,22 +994,7 @@ void BytecodeGenerator::VisitCall(Call* expr) {
} }
void BytecodeGenerator::VisitCallNew(CallNew* expr) { void BytecodeGenerator::VisitCallNew(CallNew* expr) { UNIMPLEMENTED(); }
TemporaryRegisterScope temporary_register_scope(builder());
Register constructor = temporary_register_scope.NewRegister();
Visit(expr->expression());
builder()->StoreAccumulatorInRegister(constructor);
ZoneList<Expression*>* args = expr->arguments();
if (args->length() > 0) {
Register first_arg = VisitArguments(args, &temporary_register_scope);
builder()->New(constructor, first_arg, args->length());
} else {
// The second argument here will be ignored as there are zero
// arguments. Using the constructor register avoids avoid
// allocating a temporary just to fill the operands.
builder()->New(constructor, constructor, 0);
}
}
void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
@ -1035,21 +1003,22 @@ void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
} }
// Evaluate all arguments to the runtime call. // Evaluate all arguments to the runtime call.
TemporaryRegisterScope temporary_register_scope(&builder_); ZoneList<Expression*>* args = expr->arguments();
TemporaryRegisterScope temporary_register_scope(builder());
// Ensure we always have a valid first_arg register even if there are no
// arguments to pass.
Register first_arg = temporary_register_scope.NewRegister();
for (int i = 0; i < args->length(); ++i) {
Register arg =
(i == 0) ? first_arg : temporary_register_scope.NewRegister();
Visit(args->at(i));
DCHECK_EQ(arg.index() - i, first_arg.index());
builder()->StoreAccumulatorInRegister(arg);
}
// TODO(rmcilroy): support multiple return values. // TODO(rmcilroy): support multiple return values.
DCHECK_LE(expr->function()->result_size, 1); DCHECK_LE(expr->function()->result_size, 1);
Runtime::FunctionId function_id = expr->function()->function_id; Runtime::FunctionId function_id = expr->function()->function_id;
ZoneList<Expression*>* args = expr->arguments();
Register first_arg;
if (args->length() > 0) {
first_arg = VisitArguments(args, &temporary_register_scope);
} else {
// Allocation here is just to fullfil the requirement that there
// is a register operand for the start of the arguments though
// there are zero when this is generated.
first_arg = temporary_register_scope.NewRegister();
}
builder()->CallRuntime(function_id, first_arg, args->length()); builder()->CallRuntime(function_id, first_arg, args->length());
} }

View File

@ -36,8 +36,6 @@ class BytecodeGenerator : public AstVisitor {
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
Register VisitArguments(ZoneList<Expression*>* arguments,
TemporaryRegisterScope* caller_scope);
void VisitArithmeticExpression(BinaryOperation* binop); void VisitArithmeticExpression(BinaryOperation* binop);
void VisitCommaExpression(BinaryOperation* binop); void VisitCommaExpression(BinaryOperation* binop);
void VisitLogicalOrExpression(BinaryOperation* binop); void VisitLogicalOrExpression(BinaryOperation* binop);

View File

@ -89,14 +89,11 @@ namespace interpreter {
V(LogicalNot, OperandType::kNone) \ V(LogicalNot, OperandType::kNone) \
V(TypeOf, OperandType::kNone) \ V(TypeOf, OperandType::kNone) \
\ \
/* Call operations */ \ /* Call operations. */ \
V(Call, OperandType::kReg8, OperandType::kReg8, OperandType::kCount8) \ V(Call, OperandType::kReg8, OperandType::kReg8, OperandType::kCount8) \
V(CallRuntime, OperandType::kIdx16, OperandType::kReg8, \ V(CallRuntime, OperandType::kIdx16, OperandType::kReg8, \
OperandType::kCount8) \ OperandType::kCount8) \
\ \
/* New operator */ \
V(New, OperandType::kReg8, OperandType::kReg8, OperandType::kCount8) \
\
/* Test Operators */ \ /* Test Operators */ \
V(TestEqual, OperandType::kReg8) \ V(TestEqual, OperandType::kReg8) \
V(TestNotEqual, OperandType::kReg8) \ V(TestNotEqual, OperandType::kReg8) \

View File

@ -537,25 +537,6 @@ void Interpreter::DoCallRuntime(compiler::InterpreterAssembler* assembler) {
} }
// New <constructor> <arg_count>
//
// Call operator new with |constructor| and the first argument in
// register |first_arg| and |arg_count| arguments in subsequent
//
void Interpreter::DoNew(compiler::InterpreterAssembler* assembler) {
Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_);
Node* constructor_index = __ BytecodeOperandReg8(0);
Node* constructor = __ LoadRegister(constructor_index);
Node* first_arg_reg = __ BytecodeOperandReg8(1);
Node* first_arg = __ RegisterLocation(first_arg_reg);
Node* args_count = __ BytecodeOperandCount8(2);
Node* result =
__ CallConstruct(constructor, constructor, first_arg, args_count);
__ SetAccumulator(result);
__ Dispatch();
}
// TestEqual <src> // TestEqual <src>
// //
// Test if the value in the <src> register equals the accumulator. // Test if the value in the <src> register equals the accumulator.

View File

@ -986,7 +986,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
// arguments should be consecutive above this, in the same order as // arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack. // they are to be pushed onto the stack.
// -- a1 : the target to call (can be any Object). // -- a1 : the target to call (can be any Object).
// -----------------------------------
// Find the address of the last argument. // Find the address of the last argument.
__ Addu(a3, a0, Operand(1)); // Add one for receiver. __ Addu(a3, a0, Operand(1)); // Add one for receiver.
@ -1008,34 +1007,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
} }
// static
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : argument count (not including receiver)
// -- a3 : original constructor
// -- a1 : constructor to call
// -- a2 : address of the first argument
// -----------------------------------
// Find the address of the last argument.
__ sll(t0, a0, kPointerSizeLog2);
__ Subu(t0, a2, Operand(t0));
// Push the arguments.
Label loop_header, loop_check;
__ Branch(&loop_check);
__ bind(&loop_header);
__ lw(t1, MemOperand(a2));
__ Addu(a2, a2, Operand(-kPointerSize));
__ push(t1);
__ bind(&loop_check);
__ Branch(&loop_header, gt, a2, Operand(t0));
// Call the constructor with a0, a1, and a3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
}
void Builtins::Generate_CompileLazy(MacroAssembler* masm) { void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
CallRuntimePassFunction(masm, Runtime::kCompileLazy); CallRuntimePassFunction(masm, Runtime::kCompileLazy);
GenerateTailCallToReturnedCode(masm); GenerateTailCallToReturnedCode(masm);

View File

@ -395,18 +395,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
a0, // argument count (not including receiver)
a3, // original constructor
a1, // constructor to call
a2 // address of the first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {

View File

@ -982,7 +982,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
// arguments should be consecutive above this, in the same order as // arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack. // they are to be pushed onto the stack.
// -- a1 : the target to call (can be any Object). // -- a1 : the target to call (can be any Object).
// -----------------------------------
// Find the address of the last argument. // Find the address of the last argument.
__ Daddu(a3, a0, Operand(1)); // Add one for receiver. __ Daddu(a3, a0, Operand(1)); // Add one for receiver.
@ -1004,34 +1003,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
} }
// static
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : argument count (not including receiver)
// -- a3 : original constructor
// -- a1 : constructor to call
// -- a2 : address of the first argument
// -----------------------------------
// Find the address of the last argument.
__ dsll(t0, a0, kPointerSizeLog2);
__ Dsubu(t0, a2, Operand(t0));
// Push the arguments.
Label loop_header, loop_check;
__ Branch(&loop_check);
__ bind(&loop_header);
__ ld(t1, MemOperand(a2));
__ Daddu(a2, a2, Operand(-kPointerSize));
__ push(t1);
__ bind(&loop_check);
__ Branch(&loop_header, gt, a2, Operand(t0));
// Call the constructor with a0, a1, and a3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
}
void Builtins::Generate_CompileLazy(MacroAssembler* masm) { void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
CallRuntimePassFunction(masm, Runtime::kCompileLazy); CallRuntimePassFunction(masm, Runtime::kCompileLazy);
GenerateTailCallToReturnedCode(masm); GenerateTailCallToReturnedCode(masm);

View File

@ -395,18 +395,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
a0, // argument count (not including receiver)
a3, // original constructor
a1, // constructor to call
a2 // address of the first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {

View File

@ -983,7 +983,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
// arguments should be consecutive above this, in the same order as // arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack. // they are to be pushed onto the stack.
// -- r4 : the target to call (can be any Object). // -- r4 : the target to call (can be any Object).
// -----------------------------------
// Calculate number of arguments (add one for receiver). // Calculate number of arguments (add one for receiver).
__ addi(r6, r3, Operand(1)); __ addi(r6, r3, Operand(1));
@ -1002,32 +1001,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
} }
// static
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : argument count (not including receiver)
// -- r6 : original constructor
// -- r4 : constructor to call
// -- r5 : address of the first argument
// -----------------------------------
// Calculate number of arguments (add one for receiver).
__ mr(r11, r3);
// Push the arguments.
Label loop;
__ addi(r5, r5, Operand(kPointerSize)); // Bias up for LoadPU
__ mtctr(r11);
__ bind(&loop);
__ LoadPU(r11, MemOperand(r5, -kPointerSize));
__ push(r11);
__ bdnz(&loop);
// Call the constructor with r3, r4, and r6 unmodified.
__ Jump(masm->isolate()->builtins()->Constuct(), RelocInfo::CONSTRUCT_CALL);
}
void Builtins::Generate_CompileLazy(MacroAssembler* masm) { void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
CallRuntimePassFunction(masm, Runtime::kCompileLazy); CallRuntimePassFunction(masm, Runtime::kCompileLazy);
GenerateTailCallToReturnedCode(masm); GenerateTailCallToReturnedCode(masm);

View File

@ -394,18 +394,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
r3, // argument count (not including receiver)
r6, // original constructor
r4, // constructor to call
r5 // address of the first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {

View File

@ -785,21 +785,21 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
} }
static void Generate_InterpreterPushArgs(MacroAssembler* masm, // static
bool push_receiver) { void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- rax : the number of arguments (not including the receiver) // -- rax : the number of arguments (not including the receiver)
// -- rbx : the address of the first argument to be pushed. Subsequent // -- rbx : the address of the first argument to be pushed. Subsequent
// arguments should be consecutive above this, in the same order as // arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack. // they are to be pushed onto the stack.
// ----------------------------------- // -- rdi : the target to call (can be any Object).
// Pop return address to allow tail-call after pushing arguments.
__ Pop(rdx);
// Find the address of the last argument. // Find the address of the last argument.
__ movp(rcx, rax); __ movp(rcx, rax);
if (push_receiver) {
__ addp(rcx, Immediate(1)); // Add one for receiver. __ addp(rcx, Immediate(1)); // Add one for receiver.
}
__ shlp(rcx, Immediate(kPointerSizeLog2)); __ shlp(rcx, Immediate(kPointerSizeLog2));
__ negp(rcx); __ negp(rcx);
__ addp(rcx, rbx); __ addp(rcx, rbx);
@ -813,58 +813,13 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
__ bind(&loop_check); __ bind(&loop_check);
__ cmpp(rbx, rcx); __ cmpp(rbx, rcx);
__ j(greater, &loop_header, Label::kNear); __ j(greater, &loop_header, Label::kNear);
}
// static
void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : the number of arguments (not including the receiver)
// -- rbx : the address of the first argument to be pushed. Subsequent
// arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack.
// -- rdi : the target to call (can be any Object).
// -----------------------------------
// Pop return address to allow tail-call after pushing arguments.
__ PopReturnAddressTo(kScratchRegister);
Generate_InterpreterPushArgs(masm, true);
// Call the target. // Call the target.
__ PushReturnAddressFrom(kScratchRegister); // Re-push return address. __ Push(rdx); // Re-push return address.
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
} }
// static
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : the number of arguments (not including the receiver)
// -- rdx : the original constructor (either the same as the constructor or
// the JSFunction on which new was invoked initially)
// -- rdi : the constructor to call (can be any Object)
// -- rbx : the address of the first argument to be pushed. Subsequent
// arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack.
// -----------------------------------
// Pop return address to allow tail-call after pushing arguments.
__ PopReturnAddressTo(kScratchRegister);
// Push slot for the receiver to be constructed.
__ Push(Immediate(0));
Generate_InterpreterPushArgs(masm, false);
// Push return address in preparation for the tail-call.
__ PushReturnAddressFrom(kScratchRegister);
// Call the constructor (rax, rdx, rdi passed on).
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
}
void Builtins::Generate_CompileLazy(MacroAssembler* masm) { void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
CallRuntimePassFunction(masm, Runtime::kCompileLazy); CallRuntimePassFunction(masm, Runtime::kCompileLazy);
GenerateTailCallToReturnedCode(masm); GenerateTailCallToReturnedCode(masm);

View File

@ -395,18 +395,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
rax, // argument count (not including receiver)
rdx, // original constructor
rdi, // constructor
rbx, // address of first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {

View File

@ -1015,14 +1015,14 @@ TEST(PropertyCall) {
B(LoadICSloppy), R(1), U8(vector->GetIndex(slot2)), // B(LoadICSloppy), R(1), U8(vector->GetIndex(slot2)), //
B(Star), R(0), // B(Star), R(0), //
B(Ldar), R(helper.kLastParamIndex), // B(Ldar), R(helper.kLastParamIndex), //
B(Star), R(3), // B(Star), R(2), //
B(Ldar), R(helper.kLastParamIndex), // B(Ldar), R(helper.kLastParamIndex), //
B(Add), R(3), // B(Add), R(2), //
B(Star), R(2), // B(Star), R(2), //
B(Ldar), R(helper.kLastParamIndex), // B(Ldar), R(helper.kLastParamIndex), //
B(Star), R(3), // B(Star), R(3), //
B(Call), R(0), R(1), U8(2), // B(Call), R(0), R(1), U8(2), //
B(Return), // B(Return) //
}, },
1, 1,
{"func"}}}; {"func"}}};
@ -2670,72 +2670,6 @@ TEST(TryFinally) {
} }
} }
TEST(CallNew) {
InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper;
ExpectedSnippet<InstanceType> snippets[] = {
{"function bar() { this.value = 0; }\n"
"function f() { return new bar(); }\n"
"f()",
kPointerSize,
1,
9,
{
B(LdaGlobal), _, //
B(Star), R(0), //
B(New), R(0), R(0), U8(0), //
B(Return), //
},
0},
{"function bar(x) { this.value = 18; this.x = x;}\n"
"function f() { return new bar(3); }\n"
"f()",
2 * kPointerSize,
1,
13,
{
B(LdaGlobal), _, //
B(Star), R(0), //
B(LdaSmi8), U8(3), //
B(Star), R(1), //
B(New), R(0), R(1), U8(1), //
B(Return), //
},
0},
{"function bar(w, x, y, z) {\n"
" this.value = 18;\n"
" this.x = x;\n"
" this.y = y;\n"
" this.z = z;\n"
"}\n"
"function f() { return new bar(3, 4, 5); }\n"
"f()",
4 * kPointerSize,
1,
21,
{
B(LdaGlobal), _, //
B(Star), R(0), //
B(LdaSmi8), U8(3), //
B(Star), R(1), //
B(LdaSmi8), U8(4), //
B(Star), R(2), //
B(LdaSmi8), U8(5), //
B(Star), R(3), //
B(New), R(0), R(1), U8(3), //
B(Return), //
},
0}};
for (size_t i = 0; i < arraysize(snippets); i++) {
Handle<BytecodeArray> bytecode_array =
helper.MakeBytecode(snippets[i].code_snippet, "f");
CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
}
}
} // namespace interpreter } // namespace interpreter
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8

View File

@ -1728,65 +1728,6 @@ TEST(InterpreterObjectLiterals) {
} }
TEST(InterpreterConstruct) {
HandleAndZoneScope handles;
std::string source(
"function counter() { this.count = 0; }\n"
"function " +
InterpreterTester::function_name() +
"() {\n"
" var c = new counter();\n"
" return c.count;\n"
"}");
InterpreterTester tester(handles.main_isolate(), source.c_str());
auto callable = tester.GetCallable<>();
Handle<Object> return_val = callable().ToHandleChecked();
CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0));
}
TEST(InterpreterConstructWithArgument) {
HandleAndZoneScope handles;
std::string source(
"function counter(arg0) { this.count = 17; this.x = arg0; }\n"
"function " +
InterpreterTester::function_name() +
"() {\n"
" var c = new counter(3);\n"
" return c.x;\n"
"}");
InterpreterTester tester(handles.main_isolate(), source.c_str());
auto callable = tester.GetCallable<>();
Handle<Object> return_val = callable().ToHandleChecked();
CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3));
}
TEST(InterpreterConstructWithArguments) {
HandleAndZoneScope handles;
std::string source(
"function counter(arg0, arg1) {\n"
" this.count = 7; this.x = arg0; this.y = arg1;\n"
"}\n"
"function " +
InterpreterTester::function_name() +
"() {\n"
" var c = new counter(3, 5);\n"
" return c.count + c.x + c.y;\n"
"}");
InterpreterTester tester(handles.main_isolate(), source.c_str());
auto callable = tester.GetCallable<>();
Handle<Object> return_val = callable().ToHandleChecked();
CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(15));
}
TEST(InterpreterComma) { TEST(InterpreterComma) {
HandleAndZoneScope handles; HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate(); i::Isolate* isolate = handles.main_isolate();

View File

@ -90,9 +90,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
// Emit unary operator invocations. // Emit unary operator invocations.
builder.LogicalNot().TypeOf(); builder.LogicalNot().TypeOf();
// Emit new.
builder.New(reg, reg, 0);
// Emit test operator invocations. // Emit test operator invocations.
builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
.CompareOperation(Token::Value::NE, reg, Strength::WEAK) .CompareOperation(Token::Value::NE, reg, Strength::WEAK)