Commit dea16c9a authored by machenbach's avatar machenbach Committed by Commit bot

Revert of [Interpreter] Collect type feedback for 'new' in the bytecode...

Revert of [Interpreter] Collect type feedback for 'new' in the bytecode handler (patchset #6 id:100001 of https://codereview.chromium.org/2190293003/ )

Reason for revert:
[Sheriff] Fails on nosnap debug:
https://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20nosnap%20-%20debug/builds/8403

Original issue's description:
> [Interpreter] Collect type feedback for 'new' in the bytecode handler
>
> Collect type feedback in the bytecode handler for 'new' bytecode. The
> earlier cl (https://codereview.chromium.org/2153433002/) was reverted
> because that implementation did not collect allocation site feedback.
> This regressed delta blue by an order of magnitude. This implementation
> includes collection of allocation site feedback.
>
> BUG=v8:4280, v8:4780
> LOG=N
>
> Committed: https://crrev.com/9d5e6129c4c7f9cbfe81a5fad2a470f219fe137c
> Cr-Commit-Position: refs/heads/master@{#38364}

TBR=bmeurer@chromium.org,rmcilroy@chromium.org,balazs.kilvady@imgtec.com,mythria@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:4280, v8:4780

Review-Url: https://codereview.chromium.org/2212343002
Cr-Commit-Position: refs/heads/master@{#38368}
parent 2648162d
......@@ -403,8 +403,7 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
r0, // argument count (not including receiver)
r3, // new target
r1, // constructor to call
r2, // allocation site feedback if available, undefined otherwise
r4 // address of the first argument
r2 // address of the first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -435,8 +435,7 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
x0, // argument count (not including receiver)
x3, // new target
x1, // constructor to call
x2, // allocation site feedback if available, undefined otherwise
x4 // address of the first argument
x2 // address of the first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -1189,7 +1189,6 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
__ mov(r3, Operand(r3, LSL, kPointerSizeLog2));
__ sub(r3, r2, r3);
// TODO(mythria): Add a stack check before pushing arguments.
// Push the arguments.
Generate_InterpreterPushArgs(masm, r2, r3, r4);
......@@ -1207,44 +1206,27 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
}
// static
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
MacroAssembler* masm, CallableType construct_type) {
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : argument count (not including receiver)
// -- r3 : new target
// -- r1 : constructor to call
// -- r2 : allocation site feedback if available, undefined otherwise.
// -- r4 : address of the first argument
// -- r2 : address of the first argument
// -----------------------------------
// Find the address of the last argument.
__ mov(r5, Operand(r0, LSL, kPointerSizeLog2));
__ sub(r5, r4, r5);
__ mov(r4, Operand(r0, LSL, kPointerSizeLog2));
__ sub(r4, r2, r4);
// Push a slot for the receiver to be constructed.
__ mov(ip, Operand::Zero());
__ push(ip);
// TODO(mythria): Add a stack check before pushing arguments.
// Push the arguments.
Generate_InterpreterPushArgs(masm, r4, r5, r6);
Generate_InterpreterPushArgs(masm, r2, r4, r5);
__ AssertUndefinedOrAllocationSite(r2, r5);
if (construct_type == CallableType::kJSFunction) {
__ AssertFunction(r1);
// Tail call to the function-specific construct stub (still in the caller
// context at this point).
__ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
// Jump to the construct function.
__ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
} else {
DCHECK_EQ(construct_type, CallableType::kAny);
// Call the constructor with r0, r1, and r3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
// Call the constructor with r0, r1, and r3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
......
......@@ -1186,7 +1186,6 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
__ lsl(x3, x3, kPointerSizeLog2);
__ sub(x4, x2, x3);
// TODO(mythria): Add a stack check before pushing arguments.
// Push the arguments.
Label loop_header, loop_check;
__ Mov(x5, jssp);
......@@ -1214,14 +1213,12 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
}
// static
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
MacroAssembler* masm, CallableType construct_type) {
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- x0 : argument count (not including receiver)
// -- x3 : new target
// -- x1 : constructor to call
// -- x2 : allocation site feedback if available, undefined otherwise
// -- x4 : address of the first argument
// -- x2 : address of the first argument
// -----------------------------------
// Find the address of the last argument.
......@@ -1231,38 +1228,24 @@ void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
// Set stack pointer and where to stop.
__ Mov(x6, jssp);
__ Claim(x5, 1);
__ sub(x7, x6, x5);
__ sub(x4, x6, x5);
// Push a slot for the receiver.
__ Str(xzr, MemOperand(x6, -kPointerSize, PreIndex));
Label loop_header, loop_check;
// TODO(mythria): Add a stack check before pushing arguments.
// Push the arguments.
__ B(&loop_check);
__ Bind(&loop_header);
// TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned.
__ Ldr(x5, MemOperand(x4, -kPointerSize, PostIndex));
__ Ldr(x5, MemOperand(x2, -kPointerSize, PostIndex));
__ Str(x5, MemOperand(x6, -kPointerSize, PreIndex));
__ Bind(&loop_check);
__ Cmp(x6, x7);
__ Cmp(x6, x4);
__ B(gt, &loop_header);
__ AssertUndefinedOrAllocationSite(x2, x6);
if (construct_type == CallableType::kJSFunction) {
__ AssertFunction(x1);
// Tail call to the function-specific construct stub (still in the caller
// context at this point).
__ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(x4, FieldMemOperand(x4, SharedFunctionInfo::kConstructStubOffset));
__ Add(x4, x4, Code::kHeaderSize - kHeapObjectTag);
__ Br(x4);
} else {
DCHECK_EQ(construct_type, CallableType::kAny);
// Call the constructor with x0, x1, and x3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
// Call the constructor with x0, x1, and x3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
......
......@@ -50,27 +50,5 @@ void Builtins::Generate_InterpreterPushArgsAndTailCallFunction(
CallableType::kJSFunction);
}
Handle<Code> Builtins::InterpreterPushArgsAndConstruct(
CallableType function_type) {
switch (function_type) {
case CallableType::kJSFunction:
return InterpreterPushArgsAndConstructFunction();
case CallableType::kAny:
return InterpreterPushArgsAndConstruct();
}
UNREACHABLE();
return Handle<Code>::null();
}
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
return Generate_InterpreterPushArgsAndConstructImpl(masm, CallableType::kAny);
}
void Builtins::Generate_InterpreterPushArgsAndConstructFunction(
MacroAssembler* masm) {
return Generate_InterpreterPushArgsAndConstructImpl(
masm, CallableType::kJSFunction);
}
} // namespace internal
} // namespace v8
......@@ -126,10 +126,9 @@ namespace internal {
ASM(InterpreterMarkBaselineOnReturn) \
ASM(InterpreterPushArgsAndCall) \
ASM(InterpreterPushArgsAndCallFunction) \
ASM(InterpreterPushArgsAndConstruct) \
ASM(InterpreterPushArgsAndTailCall) \
ASM(InterpreterPushArgsAndTailCallFunction) \
ASM(InterpreterPushArgsAndConstruct) \
ASM(InterpreterPushArgsAndConstructFunction) \
ASM(InterpreterEnterBytecodeDispatch) \
ASM(InterpreterOnStackReplacement) \
\
......@@ -582,7 +581,6 @@ class Builtins {
Handle<Code> InterpreterPushArgsAndCall(
TailCallMode tail_call_mode,
CallableType function_type = CallableType::kAny);
Handle<Code> InterpreterPushArgsAndConstruct(CallableType function_type);
Code* builtin(Name name) {
// Code::cast cannot be used here since we access builtins
......@@ -627,9 +625,6 @@ class Builtins {
MacroAssembler* masm, TailCallMode tail_call_mode,
CallableType function_type);
static void Generate_InterpreterPushArgsAndConstructImpl(
MacroAssembler* masm, CallableType function_type);
static void Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index);
......
......@@ -702,20 +702,19 @@ void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) {
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
Register array_limit,
Register start_address) {
Register array_limit) {
// ----------- S t a t e -------------
// -- start_address : Pointer to the last argument in the args array.
// -- 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(start_address, 0));
__ sub(start_address, Immediate(kPointerSize));
__ Push(Operand(ebx, 0));
__ sub(ebx, Immediate(kPointerSize));
__ bind(&loop_check);
__ cmp(start_address, array_limit);
__ cmp(ebx, array_limit);
__ j(greater, &loop_header, Label::kNear);
}
......@@ -741,8 +740,7 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
__ neg(ecx);
__ add(ecx, ebx);
// TODO(mythria): Add a stack check before pushing the arguments.
Generate_InterpreterPushArgs(masm, ecx, ebx);
Generate_InterpreterPushArgs(masm, ecx);
// Call the target.
__ Push(edx); // Re-push return address.
......@@ -760,115 +758,40 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
}
// static
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
MacroAssembler* masm, CallableType construct_type) {
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : the number of arguments (not including the receiver)
// -- edx : the new target
// -- edi : the constructor
// -- ebx : allocation site feedback (if available or undefined)
// -- ecx : the address of the first argument to be pushed. Subsequent
// -- 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.
// -----------------------------------
// Store edi, edx onto the stack. We need two extra registers
// so store edi, edx temporarily on stack.
// Pop return address to allow tail-call after pushing arguments.
__ Pop(ecx);
// Push edi in the slot meant for receiver. We need an extra register
// so store edi temporarily on stack.
__ Push(edi);
__ Push(edx);
// We have to pop return address and the two temporary registers before we
// can push arguments onto the stack. we do not have any free registers so
// update the stack and copy them into the correct places on the stack.
// current stack =====> required stack layout
// | | | edx | (2) <-- esp(1)
// | | | edi | (3)
// | | | return addr | (4)
// | | | arg N | (5)
// | edx | <-- esp | .... |
// | edi | | arg 0 |
// | return addr | | receiver slot |
// First increment the stack pointer to the correct location.
// we need additional slots for arguments and the receiver.
// Step 1 - compute the required increment to the stack.
__ mov(edx, eax);
__ shl(edx, kPointerSizeLog2);
__ add(edx, Immediate(kPointerSize));
#ifdef _MSC_VER
// TODO(mythria): Move it to macro assembler.
// In windows, we cannot increment the stack size by more than one page
// (mimimum page size is 4KB) without accessing at least one byte on the
// page. Check this:
// https://msdn.microsoft.com/en-us/library/aa227153(v=vs.60).aspx.
const int page_size = 4 * 1024;
Label check_offset, update_stack_pointer;
__ bind(&check_offset);
__ cmp(edx, page_size);
__ j(less, &update_stack_pointer);
__ sub(esp, Immediate(page_size));
// Just to touch the page, before we increment further.
__ mov(Operand(esp, 0), Immediate(0));
__ sub(edx, Immediate(page_size));
__ jmp(&check_offset);
__ bind(&update_stack_pointer);
#endif
// TODO(mythria): Add a stack check before updating the stack pointer.
// Step 1 - Update the stack pointer.
__ sub(esp, edx);
// Step 2 move edx to the correct location. Move edx first otherwise
// we may overwrite when eax = 0 or 1, basically when the source and
// destination overlap. We at least need one extra slot for receiver,
// so no extra checks are required to avoid copy.
__ mov(edi, Operand(esp, eax, times_pointer_size, 1 * kPointerSize));
__ mov(Operand(esp, 0), edi);
// Step 3 move edi to the correct location
__ mov(edi, Operand(esp, eax, times_pointer_size, 2 * kPointerSize));
__ mov(Operand(esp, 1 * kPointerSize), edi);
// Step 4 move return address to the correct location
__ mov(edi, Operand(esp, eax, times_pointer_size, 3 * kPointerSize));
__ mov(Operand(esp, 2 * kPointerSize), edi);
// Step 5 copy arguments to correct locations.
__ mov(edx, eax);
// Find the address of the last argument.
__ mov(edi, eax);
__ neg(edi);
__ shl(edi, kPointerSizeLog2);
__ add(edi, ebx);
Label loop_header, loop_check;
__ jmp(&loop_check);
__ bind(&loop_header);
__ mov(edi, Operand(ecx, 0));
__ mov(Operand(esp, edx, times_pointer_size, 2 * kPointerSize), edi);
__ sub(ecx, Immediate(kPointerSize));
__ sub(edx, Immediate(1));
__ bind(&loop_check);
__ cmp(edx, Immediate(0));
__ j(greater, &loop_header, Label::kNear);
Generate_InterpreterPushArgs(masm, edi);
// Restore edi and edx.
__ Pop(edx);
__ Pop(edi);
__ AssertUndefinedOrAllocationSite(ebx);
if (construct_type == CallableType::kJSFunction) {
// Tail call to the function-specific construct stub (still in the caller
// context at this point).
__ AssertFunction(edi);
__ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
__ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
__ jmp(ecx);
} else {
DCHECK_EQ(construct_type, CallableType::kAny);
// Restore the constructor from slot on stack. It was pushed at the slot
// meant for receiver.
__ mov(edi, Operand(esp, eax, times_pointer_size, 0));
// Call the constructor with unmodified eax, edi, edx values.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
// Re-push return address.
__ Push(ecx);
// Call the constructor with unmodified eax, edi, ebi values.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
......
......@@ -1198,19 +1198,17 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
}
// static
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
MacroAssembler* masm, CallableType construct_type) {
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : argument count (not including receiver)
// -- a3 : new target
// -- a1 : constructor to call
// -- a2 : allocation site feedback if available, undefined otherwise.
// -- t4 : address of the first argument
// -- a2 : address of the first argument
// -----------------------------------
// Find the address of the last argument.
__ sll(t0, a0, kPointerSizeLog2);
__ Subu(t0, t4, Operand(t0));
__ Subu(t0, a2, Operand(t0));
// Push a slot for the receiver.
__ push(zero_reg);
......@@ -1219,27 +1217,14 @@ void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
Label loop_header, loop_check;
__ Branch(&loop_check);
__ bind(&loop_header);
__ lw(t1, MemOperand(t4));
__ Addu(t4, t4, Operand(-kPointerSize));
__ lw(t1, MemOperand(a2));
__ Addu(a2, a2, Operand(-kPointerSize));
__ push(t1);
__ bind(&loop_check);
__ Branch(&loop_header, gt, t4, Operand(t0));
__ AssertUndefinedOrAllocationSite(a2, t0);
if (construct_type == CallableType::kJSFunction) {
__ AssertFunction(a1);
// Tail call to the function-specific construct stub (still in the caller
// context at this point).
__ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset));
__ Addu(at, t0, Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(at);
} else {
DCHECK_EQ(construct_type, CallableType::kAny);
// Call the constructor with a0, a1, and a3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
__ Branch(&loop_header, gt, a2, Operand(t0));
// Call the constructor with a0, a1, and a3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
......
......@@ -1190,19 +1190,17 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
}
// static
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
MacroAssembler* masm, CallableType construct_type) {
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : argument count (not including receiver)
// -- a3 : new target
// -- a1 : constructor to call
// -- a2 : allocation site feedback if available, undefined otherwise.
// -- a4 : address of the first argument
// -- a2 : address of the first argument
// -----------------------------------
// Find the address of the last argument.
__ dsll(t0, a0, kPointerSizeLog2);
__ Dsubu(t0, a4, Operand(t0));
__ Dsubu(t0, a2, Operand(t0));
// Push a slot for the receiver.
__ push(zero_reg);
......@@ -1211,27 +1209,14 @@ void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
Label loop_header, loop_check;
__ Branch(&loop_check);
__ bind(&loop_header);
__ ld(t1, MemOperand(a4));
__ Daddu(a4, a4, Operand(-kPointerSize));
__ ld(t1, MemOperand(a2));
__ Daddu(a2, a2, Operand(-kPointerSize));
__ push(t1);
__ bind(&loop_check);
__ Branch(&loop_header, gt, a4, Operand(t0));
__ AssertUndefinedOrAllocationSite(a2, t0);
if (construct_type == CallableType::kJSFunction) {
__ AssertFunction(a1);
// Tail call to the function-specific construct stub (still in the caller
// context at this point).
__ ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ ld(a4, FieldMemOperand(a4, SharedFunctionInfo::kConstructStubOffset));
__ Daddu(at, a4, Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(at);
} else {
DCHECK_EQ(construct_type, CallableType::kAny);
// Call the constructor with a0, a1, and a3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
__ Branch(&loop_header, gt, a2, Operand(t0));
// Call the constructor with a0, a1, and a3 unmodified.
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
......
......@@ -778,9 +778,7 @@ void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) {
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
Register num_args,
Register start_address,
Register scratch, bool push_receiver) {
bool push_receiver) {
// ----------- 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
......@@ -789,23 +787,23 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
// -----------------------------------
// Find the address of the last argument.
__ movp(scratch, num_args);
__ movp(rcx, rax);
if (push_receiver) {
__ addp(scratch, Immediate(1)); // Add one for receiver.
__ addp(rcx, Immediate(1)); // Add one for receiver.
}
__ shlp(scratch, Immediate(kPointerSizeLog2));
__ negp(scratch);
__ addp(scratch, start_address);
__ shlp(rcx, Immediate(kPointerSizeLog2));
__ negp(rcx);
__ addp(rcx, rbx);
// Push the arguments.
Label loop_header, loop_check;
__ j(always, &loop_check);
__ bind(&loop_header);
__ Push(Operand(start_address, 0));
__ subp(start_address, Immediate(kPointerSize));
__ Push(Operand(rbx, 0));
__ subp(rbx, Immediate(kPointerSize));
__ bind(&loop_check);
__ cmpp(start_address, scratch);
__ cmpp(rbx, rcx);
__ j(greater, &loop_header, Label::kNear);
}
......@@ -824,9 +822,7 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
// Pop return address to allow tail-call after pushing arguments.
__ PopReturnAddressTo(kScratchRegister);
// TODO(mythria): Add a stack check before pushing arguments.
// rax is readonly rcx and r8 will be modified.
Generate_InterpreterPushArgs(masm, rax, rbx, rcx, true);
Generate_InterpreterPushArgs(masm, true);
// Call the target.
__ PushReturnAddressFrom(kScratchRegister); // Re-push return address.
......@@ -844,15 +840,13 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
}
// static
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
MacroAssembler* masm, CallableType construct_type) {
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : the number of arguments (not including the receiver)
// -- rdx : the new target (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 allocation site feedback if available, undefined otherwise
// -- rcx : 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
// they are to be pushed onto the stack.
// -----------------------------------
......@@ -863,29 +857,13 @@ void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
// Push slot for the receiver to be constructed.
__ Push(Immediate(0));
// TODO(mythria): Add a stack check before pushing arguments.
// rax is readonly rcx and r8 will be modified.
Generate_InterpreterPushArgs(masm, rax, rcx, r8, false);
Generate_InterpreterPushArgs(masm, false);
// Push return address in preparation for the tail-call.
__ PushReturnAddressFrom(kScratchRegister);
__ AssertUndefinedOrAllocationSite(rbx);
if (construct_type == CallableType::kJSFunction) {
// Tail call to the function-specific construct stub (still in the caller
// context at this point).
__ AssertFunction(rdi);
__ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
__ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset));
__ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
// Jump to the constructor function (rax, rbx, rdx passed on).
__ jmp(rcx);
} else {
DCHECK_EQ(construct_type, CallableType::kAny);
// Call the constructor (rax, rdx, rdi passed on).
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
// Call the constructor (rax, rdx, rdi passed on).
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
......
......@@ -576,11 +576,9 @@ Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate,
}
// static
Callable CodeFactory::InterpreterPushArgsAndConstruct(
Isolate* isolate, CallableType function_type) {
return Callable(
isolate->builtins()->InterpreterPushArgsAndConstruct(function_type),
InterpreterPushArgsAndConstructDescriptor(isolate));
Callable CodeFactory::InterpreterPushArgsAndConstruct(Isolate* isolate) {
return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(),
InterpreterPushArgsAndConstructDescriptor(isolate));
}
// static
......
......@@ -156,8 +156,7 @@ class CodeFactory final {
static Callable InterpreterPushArgsAndCall(
Isolate* isolate, TailCallMode tail_call_mode,
CallableType function_type = CallableType::kAny);
static Callable InterpreterPushArgsAndConstruct(
Isolate* isolate, CallableType function_type = CallableType::kAny);
static Callable InterpreterPushArgsAndConstruct(Isolate* isolate);
static Callable InterpreterCEntry(Isolate* isolate, int result_size = 1);
static Callable InterpreterOnStackReplacement(Isolate* isolate);
};
......
......@@ -1094,17 +1094,12 @@ void BytecodeGraphBuilder::VisitNew() {
interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
// Slot index of 0 is used indicate no feedback slot is available. Assert
// the assumption that slot index 0 is never a valid feedback slot.
STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0);
VectorSlotPair feedback =
CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
Node* new_target = environment()->LookupAccumulator();
Node* callee = environment()->LookupRegister(callee_reg);
const Operator* call =
javascript()->CallConstruct(static_cast<int>(arg_count) + 2, feedback);
// TODO(turbofan): Pass the feedback here.
const Operator* call = javascript()->CallConstruct(
static_cast<int>(arg_count) + 2, VectorSlotPair());
Node* value = ProcessCallNewArguments(call, callee, new_target, first_arg,
arg_count + 2);
environment()->BindAccumulator(value, &states);
......
......@@ -389,8 +389,7 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
eax, // argument count (not including receiver)
edx, // new target
edi, // constructor
ebx, // allocation site feedback
ecx, // address of first argument
ebx, // address of first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -588,15 +588,13 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
Register first_arg,
size_t arg_count,
int feedback_slot_id) {
size_t arg_count) {
if (!first_arg.is_valid()) {
DCHECK_EQ(0u, arg_count);
first_arg = Register(0);
}
Output(Bytecode::kNew, RegisterOperand(constructor),
RegisterOperand(first_arg), UnsignedOperand(arg_count),
UnsignedOperand(feedback_slot_id));
RegisterOperand(first_arg), UnsignedOperand(arg_count));
return *this;
}
......
......@@ -176,7 +176,7 @@ class BytecodeArrayBuilder final : public ZoneObject {
// consecutive arguments starting at |first_arg| for the constuctor
// invocation.
BytecodeArrayBuilder& New(Register constructor, Register first_arg,
size_t arg_count, int feedback_slot);
size_t arg_count);
// Call the runtime function with |function_id|. The first argument should be
// in |first_arg| and all subsequent arguments should be in registers
......
......@@ -2619,7 +2619,7 @@ void BytecodeGenerator::VisitCall(Call* expr) {
if (expr->CallFeedbackICSlot().IsInvalid()) {
DCHECK(call_type == Call::POSSIBLY_EVAL_CALL);
// Valid type feedback slots can only be greater than kReservedIndexCount.
// We use 0 to indicate an invalid slot id. Statically assert that 0 cannot
// We use 0 to indicate an invalid slot it. Statically assert that 0 cannot
// be a valid slot id.
STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0);
feedback_slot_index = 0;
......@@ -2654,13 +2654,7 @@ void BytecodeGenerator::VisitCallSuper(Call* expr) {
// Call construct.
builder()->SetExpressionPosition(expr);
// Valid type feedback slots can only be greater than kReservedIndexCount.
// Assert that 0 cannot be valid a valid slot id.
STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0);
// Type feedback is not necessary for super constructor calls. The type
// information can be inferred in most cases. Slot id 0 indicates type
// feedback is not required.
builder()->New(constructor, first_arg, args->length(), 0);
builder()->New(constructor, first_arg, args->length());
execution_result()->SetResultInAccumulator();
}
......@@ -2677,8 +2671,7 @@ void BytecodeGenerator::VisitCallNew(CallNew* expr) {
// constructor for CallNew.
builder()
->LoadAccumulatorWithRegister(constructor)
.New(constructor, first_arg, args->length(),
feedback_index(expr->CallNewFeedbackSlot()));
.New(constructor, first_arg, args->length());
execution_result()->SetResultInAccumulator();
}
......
......@@ -197,7 +197,7 @@ namespace interpreter {
\
/* New operator */ \
V(New, AccumulatorUse::kReadWrite, OperandType::kReg, \
OperandType::kMaybeReg, OperandType::kRegCount, OperandType::kIdx) \
OperandType::kMaybeReg, OperandType::kRegCount) \
\
/* Test Operators */ \
V(TestEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
......
......@@ -489,7 +489,7 @@ Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context,
Node* is_feedback_unavailable = Word32Equal(slot_id, Int32Constant(0));
GotoIf(is_feedback_unavailable, &call);
// The checks. First, does function match the recorded monomorphic target?
// The checks. First, does rdi match the recorded monomorphic target?
Node* feedback_element = LoadFixedArrayElement(type_feedback_vector, slot_id);
Node* feedback_value = LoadWeakCellValue(feedback_element);
Node* is_monomorphic = WordEqual(function, feedback_value);
......@@ -623,202 +623,11 @@ Node* InterpreterAssembler::CallJS(Node* function, Node* context,
Node* InterpreterAssembler::CallConstruct(Node* constructor, Node* context,
Node* new_target, Node* first_arg,
Node* arg_count, Node* slot_id,
Node* type_feedback_vector) {
Label call_construct(this), js_function(this), end(this);
Variable return_value(this, MachineRepresentation::kTagged);
Variable allocation_feedback(this, MachineRepresentation::kTagged);
allocation_feedback.Bind(UndefinedConstant());
// Slot id of 0 is used to indicate no type feedback is available.
STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0);
Node* is_feedback_unavailable = Word32Equal(slot_id, Int32Constant(0));
GotoIf(is_feedback_unavailable, &call_construct);
// Check that the constructor is not a smi.
Node* is_smi = WordIsSmi(constructor);
GotoIf(is_smi, &call_construct);
// Check that constructor is a JSFunction.
Node* instance_type = LoadInstanceType(constructor);
Node* is_js_function =
WordEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE));
BranchIf(is_js_function, &js_function, &call_construct);
Bind(&js_function);
{
// Cache the called function in a feedback vector slot. Cache states
// are uninitialized, monomorphic (indicated by a JSFunction), and
// megamorphic.
// TODO(mythria/v8:5210): Check if it is better to mark extra_checks as a
// deferred block so that call_construct_function will be scheduled just
// after increment_count and in the fast path we can reduce one branch in
// the
// fast path.
Label increment_count(this), extra_checks(this),
call_construct_function(this);
Node* feedback_element =
LoadFixedArrayElement(type_feedback_vector, slot_id);
Node* feedback_value = LoadWeakCellValue(feedback_element);
Node* is_monomorphic = WordEqual(constructor, feedback_value);
BranchIf(is_monomorphic, &increment_count, &extra_checks);
Bind(&extra_checks);
{
Label mark_megamorphic(this), initialize(this),
check_allocation_site(this), check_initialized(this),
set_alloc_feedback_and_inc_count(this);
{
// Check if it is a megamorphic target
Comment("check if megamorphic");
Node* is_megamorphic = WordEqual(
feedback_element,
HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate())));
GotoIf(is_megamorphic, &call_construct_function);
Comment("check if weak cell");
Node* is_weak_cell = WordEqual(LoadMap(feedback_element),
LoadRoot(Heap::kWeakCellMapRootIndex));
GotoUnless(is_weak_cell, &check_allocation_site);
// If the weak cell is cleared, we have a new chance to become
// monomorphic.
Comment("check if weak cell is cleared");
Node* is_smi = WordIsSmi(feedback_value);
BranchIf(is_smi, &initialize, &mark_megamorphic);
}
Bind(&check_allocation_site);
{
Comment("check if it is an allocation site");
Node* is_allocation_site =
WordEqual(LoadObjectField(feedback_element, 0),
LoadRoot(Heap::kAllocationSiteMapRootIndex));
GotoUnless(is_allocation_site, &check_initialized);
// Make sure the function is the Array() function
Node* context_slot =
LoadFixedArrayElement(LoadNativeContext(context),
Int32Constant(Context::ARRAY_FUNCTION_INDEX));
Node* is_array_function = WordEqual(context_slot, constructor);
BranchIf(is_array_function, &set_alloc_feedback_and_inc_count,
&mark_megamorphic);
}
Bind(&set_alloc_feedback_and_inc_count);
{
allocation_feedback.Bind(feedback_element);
Goto(&increment_count);
}
Bind(&check_initialized);
{
// Check if it is uninitialized.
Comment("check if uninitialized");
Node* is_uninitialized = WordEqual(
feedback_element, LoadRoot(Heap::kuninitialized_symbolRootIndex));
BranchIf(is_uninitialized, &initialize, &mark_megamorphic);
}
Bind(&initialize);
{
Label initialize_count(this), create_weak_cell(this),
create_allocation_site(this);
Comment("initialize the feedback element");
// Check that it is the Array() function.
Node* context_slot =
LoadFixedArrayElement(LoadNativeContext(context),
Int32Constant(Context::ARRAY_FUNCTION_INDEX));
Node* is_array_function = WordEqual(context_slot, constructor);
BranchIf(is_array_function, &create_allocation_site, &create_weak_cell);
Bind(&create_allocation_site);
{
// TODO(mythria): Inline the creation of allocation site.
CreateAllocationSiteStub create_stub(isolate());
CallStub(create_stub.GetCallInterfaceDescriptor(),
HeapConstant(create_stub.GetCode()), context,
type_feedback_vector, SmiTag(slot_id));
Node* feedback_element =
LoadFixedArrayElement(type_feedback_vector, slot_id);
allocation_feedback.Bind(feedback_element);
Goto(&initialize_count);
}
Bind(&create_weak_cell);
{
CreateWeakCellInFeedbackVector(type_feedback_vector, SmiTag(slot_id),
constructor);
Goto(&initialize_count);
}
Bind(&initialize_count);
{
Node* call_count_slot = IntPtrAdd(slot_id, IntPtrConstant(1));
// Count is Smi, so we don't need a write barrier.
StoreFixedArrayElement(type_feedback_vector, call_count_slot,
SmiTag(Int32Constant(1)), SKIP_WRITE_BARRIER);
Goto(&call_construct_function);
}
}
Bind(&mark_megamorphic);
{
// MegamorphicSentinel is an immortal immovable object so no
// write-barrier
// is needed.
Comment("transition to megamorphic");
DCHECK(
Heap::RootIsImmortalImmovable(Heap::kmegamorphic_symbolRootIndex));
StoreFixedArrayElement(
type_feedback_vector, slot_id,
HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate())),
SKIP_WRITE_BARRIER);
Goto(&call_construct_function);
}
}
Bind(&increment_count);
{
// Increment the call count.
Comment("increment call count");
Node* call_count_slot = IntPtrAdd(slot_id, IntPtrConstant(1));
Node* call_count =
LoadFixedArrayElement(type_feedback_vector, call_count_slot);
Node* new_count = SmiAdd(call_count, SmiTag(Int32Constant(1)));
// Count is Smi, so we don't need a write barrier.
StoreFixedArrayElement(type_feedback_vector, call_count_slot, new_count,
SKIP_WRITE_BARRIER);
Goto(&call_construct_function);
}
Bind(&call_construct_function);
{
Comment("call using callConstructFunction");
Callable callable_function = CodeFactory::InterpreterPushArgsAndConstruct(
isolate(), CallableType::kJSFunction);
return_value.Bind(CallStub(callable_function.descriptor(),
HeapConstant(callable_function.code()),
context, arg_count, new_target, constructor,
allocation_feedback.value(), first_arg));
Goto(&end);
}
}
Bind(&call_construct);
{
Comment("call using callConstruct builtin");
Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(
isolate(), CallableType::kAny);
Node* code_target = HeapConstant(callable.code());
return_value.Bind(CallStub(callable.descriptor(), code_target, context,
arg_count, new_target, constructor,
UndefinedConstant(), first_arg));
Goto(&end);
}
Bind(&end);
return return_value.value();
Node* arg_count) {
Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(isolate());
Node* code_target = HeapConstant(callable.code());
return CallStub(callable.descriptor(), code_target, context, arg_count,
new_target, constructor, first_arg);
}
Node* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context,
......
......@@ -120,9 +120,7 @@ class InterpreterAssembler : public CodeStubAssembler {
compiler::Node* context,
compiler::Node* new_target,
compiler::Node* first_arg,
compiler::Node* arg_count,
compiler::Node* slot_id,
compiler::Node* type_feedback_vector);
compiler::Node* arg_count);
// Call runtime function with |arg_count| arguments and the first argument
// located at |first_arg|.
......
......@@ -1305,11 +1305,9 @@ void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) {
Node* first_arg_reg = __ BytecodeOperandReg(1);
Node* first_arg = __ RegisterLocation(first_arg_reg);
Node* args_count = __ BytecodeOperandCount(2);
Node* slot_id = __ BytecodeOperandIdx(3);
Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Node* context = __ GetContext();
Node* result = __ CallConstruct(constructor, context, new_target, first_arg,
args_count, slot_id, type_feedback_vector);
Node* result =
__ CallConstruct(constructor, context, new_target, first_arg, args_count);
__ SetAccumulator(result);
__ Dispatch();
}
......
......@@ -381,8 +381,7 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
a0, // argument count (not including receiver)
a3, // new target
a1, // constructor to call
a2, // allocation site feedback if available, undefined otherwise.
t4 // address of the first argument
a2 // address of the first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -380,8 +380,7 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
a0, // argument count (not including receiver)
a3, // new target
a1, // constructor to call
a2, // allocation site feedback if available, undefined otherwise.
a4 // address of the first argument
a2 // address of the first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -380,8 +380,7 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
rax, // argument count (not including receiver)
rdx, // new target
rdi, // constructor
rbx, // allocation site feedback if available, undefined otherwise
rcx, // address of first argument
rbx, // address of first argument
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -130,6 +130,12 @@
# TODO(mythria,4780): Related to type feedback support for Array function.
'test-feedback-vector/VectorCallFeedbackForArray': [PASS, NO_IGNITION],
# TODO(mythria,4780): Related to type feedback support for constructor.
'test-feedback-vector/VectorConstructCounts': [PASS, NO_IGNITION],
'test-heap/WeakFunctionInConstructor': [PASS, NO_IGNITION],
'test-heap/IncrementalMarkingClearsMonomorphicConstructor': [PASS, NO_IGNITION],
'test-heap/IncrementalMarkingPreservesMonomorphicConstructor': [PASS, NO_IGNITION],
# TODO(mythria,4680): Lack of code-ageing in interpreter.
'test-heap/Regress169209': [PASS, NO_IGNITION],
......@@ -144,8 +150,8 @@
# BUG(4680): Missing type feedback makes optimistic optimizations fail.
'test-cpu-profiler/DeoptUntrackedFunction': [PASS, NO_IGNITION],
# TODO(mythria, 4780): In interpreter we disable mementos when creating array
# literals.
# BUG(4680): Ignition doesn't support allocation sites currently.
'test-heap/EnsureAllocationSiteDependentCodesProcessed': [PASS, NO_IGNITION],
'test-heap/OptimizedPretenuringAllocationFolding': [PASS, NO_IGNITION],
'test-heap/OptimizedPretenuringdoubleArrayLiterals': [PASS, NO_IGNITION],
'test-heap/OptimizedPretenuringNestedDoubleLiterals': [PASS, NO_IGNITION],
......@@ -423,6 +429,12 @@
# TODO(mythria,4780): Related to type feedback support for Array function.
'test-feedback-vector/VectorCallFeedbackForArray': [FAIL],
# TODO(mythria,4780): Related to type feedback support for constructor.
'test-feedback-vector/VectorConstructCounts': [FAIL],
'test-heap/WeakFunctionInConstructor': [FAIL],
'test-heap/IncrementalMarkingClearsMonomorphicConstructor': [FAIL],
'test-heap/IncrementalMarkingPreservesMonomorphicConstructor': [FAIL],
# TODO(mythria,4680): Lack of code-ageing in interpreter.
'test-heap/Regress169209': [FAIL],
......@@ -434,8 +446,8 @@
'test-cpu-profiler/CollectDeoptEvents': [FAIL],
'test-cpu-profiler/DeoptUntrackedFunction': [FAIL],
# TODO(mythria, 4780): In interpreter we disable mementos when creating array
# literals.
# BUG(4680): Ignition doesn't support allocation sites currently.
'test-heap/EnsureAllocationSiteDependentCodesProcessed': [FAIL],
'test-heap/OptimizedPretenuringAllocationFolding': [FAIL],
'test-heap/OptimizedPretenuringdoubleArrayLiterals': [FAIL],
'test-heap/OptimizedPretenuringNestedDoubleLiterals': [FAIL],
......
......@@ -16,12 +16,12 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 12
bytecode array length: 11
bytecodes: [
/* 45 E> */ B(StackCheck),
/* 50 S> */ B(LdrGlobal), U8(3), R(0),
B(Ldar), R(0),
/* 57 E> */ B(New), R(0), R(0), U8(0), U8(1),
/* 57 E> */ B(New), R(0), R(0), U8(0),
/* 68 S> */ B(Return),
]
constant pool: [
......@@ -37,14 +37,14 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 16
bytecode array length: 15
bytecodes: [
/* 58 E> */ B(StackCheck),
/* 63 S> */ B(LdrGlobal), U8(3), R(0),
B(LdaSmi), U8(3),
B(Star), R(1),
B(Ldar), R(0),
/* 70 E> */ B(New), R(0), R(1), U8(1), U8(1),
/* 70 E> */ B(New), R(0), R(1), U8(1),
/* 82 S> */ B(Return),
]
constant pool: [
......@@ -65,7 +65,7 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 24
bytecode array length: 23
bytecodes: [
/* 100 E> */ B(StackCheck),
/* 105 S> */ B(LdrGlobal), U8(3), R(0),
......@@ -76,7 +76,7 @@ bytecodes: [
B(LdaSmi), U8(5),
B(Star), R(3),
B(Ldar), R(0),
/* 112 E> */ B(New), R(0), R(1), U8(3), U8(1),
/* 112 E> */ B(New), R(0), R(1), U8(3),
/* 130 S> */ B(Return),
]
constant pool: [
......
......@@ -127,7 +127,7 @@ snippet: "
"
frame size: 5
parameter count: 1
bytecode array length: 106
bytecode array length: 105
bytecodes: [
B(Mov), R(closure), R(1),
B(Mov), R(new_target), R(0),
......@@ -147,7 +147,7 @@ bytecodes: [
B(LdaConstant), U8(1),
B(Star), R(4),
/* 118 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(4), U8(1),
/* 118 E> */ B(New), R(2), R(3), U8(1), U8(0),
/* 118 E> */ B(New), R(2), R(3), U8(1),
B(Star), R(2),
B(Ldar), R(this),
B(JumpIfNotHole), U8(4),
......@@ -195,7 +195,7 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 102
bytecode array length: 101
bytecodes: [
B(Mov), R(closure), R(1),
B(Mov), R(new_target), R(0),
......@@ -213,7 +213,7 @@ bytecodes: [
B(LdaConstant), U8(1),
B(Star), R(3),
/* 117 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
/* 117 E> */ B(New), R(2), R(0), U8(0), U8(0),
/* 117 E> */ B(New), R(2), R(0), U8(0),
B(Star), R(2),
B(Ldar), R(this),
B(JumpIfNotHole), U8(4),
......
......@@ -196,7 +196,7 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 73
bytecode array length: 72
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(3),
......@@ -227,7 +227,7 @@ bytecodes: [
B(Star), R(5),
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(5), U8(1),
B(Star), R(4),
/* 94 E> */ B(New), R(4), R(0), U8(0), U8(3),
/* 94 E> */ B(New), R(4), R(0), U8(0),
/* 103 S> */ B(Return),
]
constant pool: [
......
......@@ -223,12 +223,9 @@
############################################################################
# Ignition
# TODO(mythria, 4780): Related to lack of allocation site feedback for calls.
'regress/regress-4121': [PASS, NO_IGNITION],
# TODO(mythria, 4780): In interpreter we disable mementos when creating array
# literals.
# TODO(mythria, 4780): Related to type feedback for calls in interpreter.
'array-literal-feedback': [PASS, NO_IGNITION],
'regress/regress-4121': [PASS, NO_IGNITION],
# TODO(4680): Test doesn't know about three tier compiler pipeline.
'assert-opt-and-deopt': [PASS, NO_IGNITION],
......@@ -264,6 +261,7 @@
'smi-mul-const': [PASS, NO_IGNITION],
'smi-mul': [PASS, NO_IGNITION],
'unary-minus-deopt': [PASS, NO_IGNITION],
'array-constructor-feedback': [PASS, NO_IGNITION],
'array-feedback': [PASS, NO_IGNITION],
'allocation-site-info': [PASS, NO_IGNITION],
......@@ -704,14 +702,11 @@
##############################################################################
['variant == ignition_turbofan', {
# TODO(mythria, 4780): Related to lack of allocation site feedback for calls
# in interpreter.
# TODO(mythria, 4780): Related to type feedback for calls in interpreter.
'array-literal-feedback': [FAIL],
'regress/regress-4121': [FAIL],
'array-constructor-feedback': [FAIL],
'array-feedback': [FAIL],
# TODO(mythria, 4780): In interpreter we disable mementos when creating array
# literals.
'array-literal-feedback': [FAIL],
'allocation-site-info': [FAIL],
'wasm/asm-wasm-f32': [PASS, ['arch in [arm64]', SKIP]],
......
......@@ -166,8 +166,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
builder.Delete(reg, LanguageMode::SLOPPY).Delete(reg, LanguageMode::STRICT);
// Emit new.
builder.New(reg, reg, 0, 1);
builder.New(wide, wide, 0, 1);
builder.New(reg, reg, 0);
builder.New(wide, wide, 0);
// Emit test operator invocations.
builder.CompareOperation(Token::Value::EQ, reg)
......@@ -458,7 +458,7 @@ TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) {
// Ensure temporaries are used so not optimized away by the
// register optimizer.
builder.New(Register(locals + contexts), Register(locals + contexts),
static_cast<size_t>(temps), 0);
static_cast<size_t>(temps));
}
builder.Return();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment