Reland "[deoptimizer] Change deopt entries into builtins"

This is a reland of 7f58ced72e

It fixes the different exit size emitted on x64/Atom CPUs due to
performance tuning in TurboAssembler::Call. Additionally, add
cctests to verify the fixed size exits.

Original change's description:
> [deoptimizer] Change deopt entries into builtins
>
> While the overall goal of this commit is to change deoptimization
> entries into builtins, there are multiple related things happening:
>
> - Deoptimization entries, formerly stubs (i.e. Code objects generated
>   at runtime, guaranteed to be immovable), have been converted into
>   builtins. The major restriction is that we now need to preserve the
>   kRootRegister, which was formerly used on most architectures to pass
>   the deoptimization id. The solution differs based on platform.
> - Renamed DEOPT_ENTRIES_OR_FOR_TESTING code kind to FOR_TESTING.
> - Removed heap/ support for immovable Code generation.
> - Removed the DeserializerData class (no longer needed).
> - arm64: to preserve 4-byte deopt exits, introduced a new optimization
>   in which the final jump to the deoptimization entry is generated
>   once per Code object, and deopt exits can continue to emit a
>   near-call.
> - arm,ia32,x64: change to fixed-size deopt exits. This reduces exit
>   sizes by 4/8, 5, and 5 bytes, respectively.
>
> On arm the deopt exit size is reduced from 12 (or 16) bytes to 8 bytes
> by using the same strategy as on arm64 (recalc deopt id from return
> address). Before:
>
>  e300a002       movw r10, <id>
>  e59fc024       ldr ip, [pc, <entry offset>]
>  e12fff3c       blx ip
>
> After:
>
>  e59acb35       ldr ip, [r10, <entry offset>]
>  e12fff3c       blx ip
>
> On arm64 the deopt exit size remains 4 bytes (or 8 bytes in same cases
> with CFI). Additionally, up to 4 builtin jumps are emitted per Code
> object (max 32 bytes added overhead per Code object). Before:
>
>  9401cdae       bl <entry offset>
>
> After:
>
>  # eager deoptimization entry jump.
>  f95b1f50       ldr x16, [x26, <eager entry offset>]
>  d61f0200       br x16
>  # lazy deoptimization entry jump.
>  f95b2b50       ldr x16, [x26, <lazy entry offset>]
>  d61f0200       br x16
>  # the deopt exit.
>  97fffffc       bl <eager deoptimization entry jump offset>
>
> On ia32 the deopt exit size is reduced from 10 to 5 bytes. Before:
>
>  bb00000000     mov ebx,<id>
>  e825f5372b     call <entry>
>
> After:
>
>  e8ea2256ba     call <entry>
>
> On x64 the deopt exit size is reduced from 12 to 7 bytes. Before:
>
>  49c7c511000000 REX.W movq r13,<id>
>  e8ea2f0700     call <entry>
>
> After:
>
>  41ff9560360000 call [r13+<entry offset>]
>
> Bug: v8:8661,v8:8768
> Change-Id: I13e30aedc360474dc818fecc528ce87c3bfeed42
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2465834
> Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#70597}

Tbr: ulan@chromium.org, tebbi@chromium.org, rmcilroy@chromium.org
Bug: v8:8661,v8:8768,chromium:1140165
Change-Id: Ibcd5c39c58a70bf2b2ac221aa375fc68d495e144
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2485506
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70655}
This commit is contained in:
Jakob Gruber 2020-10-20 13:41:06 +02:00 committed by Commit Bot
parent 7eeac39fff
commit fbfa9bf4ec
77 changed files with 1919 additions and 2362 deletions

View File

@ -3166,6 +3166,250 @@ void Builtins::Generate_MemCopyUint8Uint8(MacroAssembler* masm) {
__ Ret();
}
namespace {
// This code tries to be close to ia32 code so that any changes can be
// easily ported.
void Generate_DeoptimizationEntry(MacroAssembler* masm,
DeoptimizeKind deopt_kind) {
Isolate* isolate = masm->isolate();
static constexpr int kDoubleRegsSize =
kDoubleSize * DwVfpRegister::kNumRegisters;
// Save all allocatable VFP registers before messing with them.
{
// We use a run-time check for VFP32DREGS.
CpuFeatureScope scope(masm, VFP32DREGS,
CpuFeatureScope::kDontCheckSupported);
UseScratchRegisterScope temps(masm);
Register scratch = temps.Acquire();
// Check CPU flags for number of registers, setting the Z condition flag.
__ CheckFor32DRegs(scratch);
// Push registers d0-d15, and possibly d16-d31, on the stack.
// If d16-d31 are not pushed, decrease the stack pointer instead.
__ vstm(db_w, sp, d16, d31, ne);
// Okay to not call AllocateStackSpace here because the size is a known
// small number and we need to use condition codes.
__ sub(sp, sp, Operand(16 * kDoubleSize), LeaveCC, eq);
__ vstm(db_w, sp, d0, d15);
}
// Save all general purpose registers before messing with them.
static constexpr int kNumberOfRegisters = Register::kNumRegisters;
STATIC_ASSERT(kNumberOfRegisters == 16);
// Everything but pc, lr and ip which will be saved but not restored.
RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit();
// Push all 16 registers (needed to populate FrameDescription::registers_).
// TODO(v8:1588): Note that using pc with stm is deprecated, so we should
// perhaps handle this a bit differently.
__ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit());
{
UseScratchRegisterScope temps(masm);
Register scratch = temps.Acquire();
__ Move(scratch, ExternalReference::Create(
IsolateAddressId::kCEntryFPAddress, isolate));
__ str(fp, MemOperand(scratch));
}
static constexpr int kSavedRegistersAreaSize =
(kNumberOfRegisters * kPointerSize) + kDoubleRegsSize;
__ mov(r2, Operand(Deoptimizer::kFixedExitSizeMarker));
// Get the address of the location in the code object (r3) (return
// address for lazy deoptimization) and compute the fp-to-sp delta in
// register r4.
__ mov(r3, lr);
__ add(r4, sp, Operand(kSavedRegistersAreaSize));
__ sub(r4, fp, r4);
// Allocate a new deoptimizer object.
// Pass four arguments in r0 to r3 and fifth argument on stack.
__ PrepareCallCFunction(6);
__ mov(r0, Operand(0));
Label context_check;
__ ldr(r1, MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset));
__ JumpIfSmi(r1, &context_check);
__ ldr(r0, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ bind(&context_check);
__ mov(r1, Operand(static_cast<int>(deopt_kind)));
// r2: bailout id already loaded.
// r3: code address or 0 already loaded.
__ str(r4, MemOperand(sp, 0 * kPointerSize)); // Fp-to-sp delta.
__ Move(r5, ExternalReference::isolate_address(isolate));
__ str(r5, MemOperand(sp, 1 * kPointerSize)); // Isolate.
// Call Deoptimizer::New().
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::new_deoptimizer_function(), 6);
}
// Preserve "deoptimizer" object in register r0 and get the input
// frame descriptor pointer to r1 (deoptimizer->input_);
__ ldr(r1, MemOperand(r0, Deoptimizer::input_offset()));
// Copy core registers into FrameDescription::registers_[kNumRegisters].
DCHECK_EQ(Register::kNumRegisters, kNumberOfRegisters);
for (int i = 0; i < kNumberOfRegisters; i++) {
int offset = (i * kPointerSize) + FrameDescription::registers_offset();
__ ldr(r2, MemOperand(sp, i * kPointerSize));
__ str(r2, MemOperand(r1, offset));
}
// Copy VFP registers to
// double_registers_[DoubleRegister::kNumAllocatableRegisters]
int double_regs_offset = FrameDescription::double_registers_offset();
const RegisterConfiguration* config = RegisterConfiguration::Default();
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
int dst_offset = code * kDoubleSize + double_regs_offset;
int src_offset = code * kDoubleSize + kNumberOfRegisters * kPointerSize;
__ vldr(d0, sp, src_offset);
__ vstr(d0, r1, dst_offset);
}
// Mark the stack as not iterable for the CPU profiler which won't be able to
// walk the stack without the return address.
{
UseScratchRegisterScope temps(masm);
Register is_iterable = temps.Acquire();
Register zero = r4;
__ Move(is_iterable, ExternalReference::stack_is_iterable_address(isolate));
__ mov(zero, Operand(0));
__ strb(zero, MemOperand(is_iterable));
}
// Remove the saved registers from the stack.
__ add(sp, sp, Operand(kSavedRegistersAreaSize));
// Compute a pointer to the unwinding limit in register r2; that is
// the first stack slot not part of the input frame.
__ ldr(r2, MemOperand(r1, FrameDescription::frame_size_offset()));
__ add(r2, r2, sp);
// Unwind the stack down to - but not including - the unwinding
// limit and copy the contents of the activation frame to the input
// frame description.
__ add(r3, r1, Operand(FrameDescription::frame_content_offset()));
Label pop_loop;
Label pop_loop_header;
__ b(&pop_loop_header);
__ bind(&pop_loop);
__ pop(r4);
__ str(r4, MemOperand(r3, 0));
__ add(r3, r3, Operand(sizeof(uint32_t)));
__ bind(&pop_loop_header);
__ cmp(r2, sp);
__ b(ne, &pop_loop);
// Compute the output frame in the deoptimizer.
__ push(r0); // Preserve deoptimizer object across call.
// r0: deoptimizer object; r1: scratch.
__ PrepareCallCFunction(1);
// Call Deoptimizer::ComputeOutputFrames().
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::compute_output_frames_function(), 1);
}
__ pop(r0); // Restore deoptimizer object (class Deoptimizer).
__ ldr(sp, MemOperand(r0, Deoptimizer::caller_frame_top_offset()));
// Replace the current (input) frame with the output frames.
Label outer_push_loop, inner_push_loop, outer_loop_header, inner_loop_header;
// Outer loop state: r4 = current "FrameDescription** output_",
// r1 = one past the last FrameDescription**.
__ ldr(r1, MemOperand(r0, Deoptimizer::output_count_offset()));
__ ldr(r4, MemOperand(r0, Deoptimizer::output_offset())); // r4 is output_.
__ add(r1, r4, Operand(r1, LSL, 2));
__ jmp(&outer_loop_header);
__ bind(&outer_push_loop);
// Inner loop state: r2 = current FrameDescription*, r3 = loop index.
__ ldr(r2, MemOperand(r4, 0)); // output_[ix]
__ ldr(r3, MemOperand(r2, FrameDescription::frame_size_offset()));
__ jmp(&inner_loop_header);
__ bind(&inner_push_loop);
__ sub(r3, r3, Operand(sizeof(uint32_t)));
__ add(r6, r2, Operand(r3));
__ ldr(r6, MemOperand(r6, FrameDescription::frame_content_offset()));
__ push(r6);
__ bind(&inner_loop_header);
__ cmp(r3, Operand::Zero());
__ b(ne, &inner_push_loop); // test for gt?
__ add(r4, r4, Operand(kPointerSize));
__ bind(&outer_loop_header);
__ cmp(r4, r1);
__ b(lt, &outer_push_loop);
__ ldr(r1, MemOperand(r0, Deoptimizer::input_offset()));
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
DwVfpRegister reg = DwVfpRegister::from_code(code);
int src_offset = code * kDoubleSize + double_regs_offset;
__ vldr(reg, r1, src_offset);
}
// Push pc and continuation from the last output frame.
__ ldr(r6, MemOperand(r2, FrameDescription::pc_offset()));
__ push(r6);
__ ldr(r6, MemOperand(r2, FrameDescription::continuation_offset()));
__ push(r6);
// Push the registers from the last output frame.
for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
int offset = (i * kPointerSize) + FrameDescription::registers_offset();
__ ldr(r6, MemOperand(r2, offset));
__ push(r6);
}
// Restore the registers from the stack.
__ ldm(ia_w, sp, restored_regs); // all but pc registers.
{
UseScratchRegisterScope temps(masm);
Register is_iterable = temps.Acquire();
Register one = r4;
__ Move(is_iterable, ExternalReference::stack_is_iterable_address(isolate));
__ mov(one, Operand(1));
__ strb(one, MemOperand(is_iterable));
}
// Remove sp, lr and pc.
__ Drop(3);
{
UseScratchRegisterScope temps(masm);
Register scratch = temps.Acquire();
__ pop(scratch); // get continuation, leave pc on stack
__ pop(lr);
__ Jump(scratch);
}
__ stop();
}
} // namespace
void Builtins::Generate_DeoptimizationEntry_Eager(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kEager);
}
void Builtins::Generate_DeoptimizationEntry_Soft(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kSoft);
}
void Builtins::Generate_DeoptimizationEntry_Bailout(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kBailout);
}
void Builtins::Generate_DeoptimizationEntry_Lazy(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kLazy);
}
#undef __
} // namespace internal

View File

@ -3619,6 +3619,297 @@ void Builtins::Generate_DirectCEntry(MacroAssembler* masm) {
__ Ret();
}
namespace {
void CopyRegListToFrame(MacroAssembler* masm, const Register& dst,
int dst_offset, const CPURegList& reg_list,
const Register& temp0, const Register& temp1,
int src_offset = 0) {
DCHECK_EQ(reg_list.Count() % 2, 0);
UseScratchRegisterScope temps(masm);
CPURegList copy_to_input = reg_list;
int reg_size = reg_list.RegisterSizeInBytes();
DCHECK_EQ(temp0.SizeInBytes(), reg_size);
DCHECK_EQ(temp1.SizeInBytes(), reg_size);
// Compute some temporary addresses to avoid having the macro assembler set
// up a temp with an offset for accesses out of the range of the addressing
// mode.
Register src = temps.AcquireX();
masm->Add(src, sp, src_offset);
masm->Add(dst, dst, dst_offset);
// Write reg_list into the frame pointed to by dst.
for (int i = 0; i < reg_list.Count(); i += 2) {
masm->Ldp(temp0, temp1, MemOperand(src, i * reg_size));
CPURegister reg0 = copy_to_input.PopLowestIndex();
CPURegister reg1 = copy_to_input.PopLowestIndex();
int offset0 = reg0.code() * reg_size;
int offset1 = reg1.code() * reg_size;
// Pair up adjacent stores, otherwise write them separately.
if (offset1 == offset0 + reg_size) {
masm->Stp(temp0, temp1, MemOperand(dst, offset0));
} else {
masm->Str(temp0, MemOperand(dst, offset0));
masm->Str(temp1, MemOperand(dst, offset1));
}
}
masm->Sub(dst, dst, dst_offset);
}
void RestoreRegList(MacroAssembler* masm, const CPURegList& reg_list,
const Register& src_base, int src_offset) {
DCHECK_EQ(reg_list.Count() % 2, 0);
UseScratchRegisterScope temps(masm);
CPURegList restore_list = reg_list;
int reg_size = restore_list.RegisterSizeInBytes();
// Compute a temporary addresses to avoid having the macro assembler set
// up a temp with an offset for accesses out of the range of the addressing
// mode.
Register src = temps.AcquireX();
masm->Add(src, src_base, src_offset);
// No need to restore padreg.
restore_list.Remove(padreg);
// Restore every register in restore_list from src.
while (!restore_list.IsEmpty()) {
CPURegister reg0 = restore_list.PopLowestIndex();
CPURegister reg1 = restore_list.PopLowestIndex();
int offset0 = reg0.code() * reg_size;
if (reg1 == NoCPUReg) {
masm->Ldr(reg0, MemOperand(src, offset0));
break;
}
int offset1 = reg1.code() * reg_size;
// Pair up adjacent loads, otherwise read them separately.
if (offset1 == offset0 + reg_size) {
masm->Ldp(reg0, reg1, MemOperand(src, offset0));
} else {
masm->Ldr(reg0, MemOperand(src, offset0));
masm->Ldr(reg1, MemOperand(src, offset1));
}
}
}
void Generate_DeoptimizationEntry(MacroAssembler* masm,
DeoptimizeKind deopt_kind) {
Isolate* isolate = masm->isolate();
// TODO(all): This code needs to be revisited. We probably only need to save
// caller-saved registers here. Callee-saved registers can be stored directly
// in the input frame.
// Save all allocatable double registers.
CPURegList saved_double_registers(
CPURegister::kVRegister, kDRegSizeInBits,
RegisterConfiguration::Default()->allocatable_double_codes_mask());
DCHECK_EQ(saved_double_registers.Count() % 2, 0);
__ PushCPURegList(saved_double_registers);
// We save all the registers except sp, lr, platform register (x18) and the
// masm scratches.
CPURegList saved_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 28);
saved_registers.Remove(ip0);
saved_registers.Remove(ip1);
saved_registers.Remove(x18);
saved_registers.Combine(fp);
saved_registers.Align();
DCHECK_EQ(saved_registers.Count() % 2, 0);
__ PushCPURegList(saved_registers);
__ Mov(x3, Operand(ExternalReference::Create(
IsolateAddressId::kCEntryFPAddress, isolate)));
__ Str(fp, MemOperand(x3));
const int kSavedRegistersAreaSize =
(saved_registers.Count() * kXRegSize) +
(saved_double_registers.Count() * kDRegSize);
// Floating point registers are saved on the stack above core registers.
const int kDoubleRegistersOffset = saved_registers.Count() * kXRegSize;
Register bailout_id = x2;
Register code_object = x3;
Register fp_to_sp = x4;
__ Mov(bailout_id, Deoptimizer::kFixedExitSizeMarker);
// Get the address of the location in the code object. This is the return
// address for lazy deoptimization.
__ Mov(code_object, lr);
// Compute the fp-to-sp delta.
__ Add(fp_to_sp, sp, kSavedRegistersAreaSize);
__ Sub(fp_to_sp, fp, fp_to_sp);
// Allocate a new deoptimizer object.
__ Ldr(x1, MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset));
// Ensure we can safely load from below fp.
DCHECK_GT(kSavedRegistersAreaSize, -StandardFrameConstants::kFunctionOffset);
__ Ldr(x0, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
// If x1 is a smi, zero x0.
__ Tst(x1, kSmiTagMask);
__ CzeroX(x0, eq);
__ Mov(x1, static_cast<int>(deopt_kind));
// Following arguments are already loaded:
// - x2: bailout id
// - x3: code object address
// - x4: fp-to-sp delta
__ Mov(x5, ExternalReference::isolate_address(isolate));
{
// Call Deoptimizer::New().
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::new_deoptimizer_function(), 6);
}
// Preserve "deoptimizer" object in register x0.
Register deoptimizer = x0;
// Get the input frame descriptor pointer.
__ Ldr(x1, MemOperand(deoptimizer, Deoptimizer::input_offset()));
// Copy core registers into the input frame.
CopyRegListToFrame(masm, x1, FrameDescription::registers_offset(),
saved_registers, x2, x3);
// Copy double registers to the input frame.
CopyRegListToFrame(masm, x1, FrameDescription::double_registers_offset(),
saved_double_registers, x2, x3, kDoubleRegistersOffset);
// Mark the stack as not iterable for the CPU profiler which won't be able to
// walk the stack without the return address.
{
UseScratchRegisterScope temps(masm);
Register is_iterable = temps.AcquireX();
__ Mov(is_iterable, ExternalReference::stack_is_iterable_address(isolate));
__ strb(xzr, MemOperand(is_iterable));
}
// Remove the saved registers from the stack.
DCHECK_EQ(kSavedRegistersAreaSize % kXRegSize, 0);
__ Drop(kSavedRegistersAreaSize / kXRegSize);
// Compute a pointer to the unwinding limit in register x2; that is
// the first stack slot not part of the input frame.
Register unwind_limit = x2;
__ Ldr(unwind_limit, MemOperand(x1, FrameDescription::frame_size_offset()));
// Unwind the stack down to - but not including - the unwinding
// limit and copy the contents of the activation frame to the input
// frame description.
__ Add(x3, x1, FrameDescription::frame_content_offset());
__ SlotAddress(x1, 0);
__ Lsr(unwind_limit, unwind_limit, kSystemPointerSizeLog2);
__ Mov(x5, unwind_limit);
__ CopyDoubleWords(x3, x1, x5);
__ Drop(unwind_limit);
// Compute the output frame in the deoptimizer.
__ Push(padreg, x0); // Preserve deoptimizer object across call.
{
// Call Deoptimizer::ComputeOutputFrames().
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::compute_output_frames_function(), 1);
}
__ Pop(x4, padreg); // Restore deoptimizer object (class Deoptimizer).
{
UseScratchRegisterScope temps(masm);
Register scratch = temps.AcquireX();
__ Ldr(scratch, MemOperand(x4, Deoptimizer::caller_frame_top_offset()));
__ Mov(sp, scratch);
}
// Replace the current (input) frame with the output frames.
Label outer_push_loop, outer_loop_header;
__ Ldrsw(x1, MemOperand(x4, Deoptimizer::output_count_offset()));
__ Ldr(x0, MemOperand(x4, Deoptimizer::output_offset()));
__ Add(x1, x0, Operand(x1, LSL, kSystemPointerSizeLog2));
__ B(&outer_loop_header);
__ Bind(&outer_push_loop);
Register current_frame = x2;
Register frame_size = x3;
__ Ldr(current_frame, MemOperand(x0, kSystemPointerSize, PostIndex));
__ Ldr(x3, MemOperand(current_frame, FrameDescription::frame_size_offset()));
__ Lsr(frame_size, x3, kSystemPointerSizeLog2);
__ Claim(frame_size);
__ Add(x7, current_frame, FrameDescription::frame_content_offset());
__ SlotAddress(x6, 0);
__ CopyDoubleWords(x6, x7, frame_size);
__ Bind(&outer_loop_header);
__ Cmp(x0, x1);
__ B(lt, &outer_push_loop);
__ Ldr(x1, MemOperand(x4, Deoptimizer::input_offset()));
RestoreRegList(masm, saved_double_registers, x1,
FrameDescription::double_registers_offset());
{
UseScratchRegisterScope temps(masm);
Register is_iterable = temps.AcquireX();
Register one = x4;
__ Mov(is_iterable, ExternalReference::stack_is_iterable_address(isolate));
__ Mov(one, Operand(1));
__ strb(one, MemOperand(is_iterable));
}
// TODO(all): ARM copies a lot (if not all) of the last output frame onto the
// stack, then pops it all into registers. Here, we try to load it directly
// into the relevant registers. Is this correct? If so, we should improve the
// ARM code.
// Restore registers from the last output frame.
// Note that lr is not in the list of saved_registers and will be restored
// later. We can use it to hold the address of last output frame while
// reloading the other registers.
DCHECK(!saved_registers.IncludesAliasOf(lr));
Register last_output_frame = lr;
__ Mov(last_output_frame, current_frame);
RestoreRegList(masm, saved_registers, last_output_frame,
FrameDescription::registers_offset());
UseScratchRegisterScope temps(masm);
temps.Exclude(x17);
Register continuation = x17;
__ Ldr(continuation, MemOperand(last_output_frame,
FrameDescription::continuation_offset()));
__ Ldr(lr, MemOperand(last_output_frame, FrameDescription::pc_offset()));
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
__ Autibsp();
#endif
__ Br(continuation);
}
} // namespace
void Builtins::Generate_DeoptimizationEntry_Eager(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kEager);
}
void Builtins::Generate_DeoptimizationEntry_Soft(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kSoft);
}
void Builtins::Generate_DeoptimizationEntry_Bailout(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kBailout);
}
void Builtins::Generate_DeoptimizationEntry_Lazy(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kLazy);
}
#undef __
} // namespace internal

View File

@ -138,6 +138,10 @@ namespace internal {
TFC(CompileLazyDeoptimizedCode, JSTrampoline) \
TFC(InstantiateAsmJs, JSTrampoline) \
ASM(NotifyDeoptimized, Dummy) \
ASM(DeoptimizationEntry_Eager, DeoptimizationEntry) \
ASM(DeoptimizationEntry_Soft, DeoptimizationEntry) \
ASM(DeoptimizationEntry_Bailout, DeoptimizationEntry) \
ASM(DeoptimizationEntry_Lazy, DeoptimizationEntry) \
\
/* Trampolines called when returning from a deoptimization that expects */ \
/* to continue in a JavaScript builtin to finish the functionality of a */ \

View File

@ -3816,6 +3816,205 @@ void Builtins::Generate_MemMove(MacroAssembler* masm) {
MemMoveEmitPopAndReturn(masm);
}
namespace {
void Generate_DeoptimizationEntry(MacroAssembler* masm,
DeoptimizeKind deopt_kind) {
Isolate* isolate = masm->isolate();
// Save all general purpose registers before messing with them.
const int kNumberOfRegisters = Register::kNumRegisters;
const int kDoubleRegsSize = kDoubleSize * XMMRegister::kNumRegisters;
__ AllocateStackSpace(kDoubleRegsSize);
const RegisterConfiguration* config = RegisterConfiguration::Default();
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
XMMRegister xmm_reg = XMMRegister::from_code(code);
int offset = code * kDoubleSize;
__ movsd(Operand(esp, offset), xmm_reg);
}
__ pushad();
ExternalReference c_entry_fp_address =
ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate);
__ mov(masm->ExternalReferenceAsOperand(c_entry_fp_address, esi), ebp);
const int kSavedRegistersAreaSize =
kNumberOfRegisters * kSystemPointerSize + kDoubleRegsSize;
// Get the address of the location in the code object
// and compute the fp-to-sp delta in register edx.
__ mov(ecx, Operand(esp, kSavedRegistersAreaSize));
__ lea(edx, Operand(esp, kSavedRegistersAreaSize + 1 * kSystemPointerSize));
__ sub(edx, ebp);
__ neg(edx);
// Allocate a new deoptimizer object.
__ PrepareCallCFunction(6, eax);
__ mov(eax, Immediate(0));
Label context_check;
__ mov(edi, Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset));
__ JumpIfSmi(edi, &context_check);
__ mov(eax, Operand(ebp, StandardFrameConstants::kFunctionOffset));
__ bind(&context_check);
__ mov(Operand(esp, 0 * kSystemPointerSize), eax); // Function.
__ mov(Operand(esp, 1 * kSystemPointerSize),
Immediate(static_cast<int>(deopt_kind)));
__ mov(Operand(esp, 2 * kSystemPointerSize),
Immediate(Deoptimizer::kFixedExitSizeMarker)); // Bailout id.
__ mov(Operand(esp, 3 * kSystemPointerSize), ecx); // Code address or 0.
__ mov(Operand(esp, 4 * kSystemPointerSize), edx); // Fp-to-sp delta.
__ Move(Operand(esp, 5 * kSystemPointerSize),
Immediate(ExternalReference::isolate_address(masm->isolate())));
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::new_deoptimizer_function(), 6);
}
// Preserve deoptimizer object in register eax and get the input
// frame descriptor pointer.
__ mov(esi, Operand(eax, Deoptimizer::input_offset()));
// Fill in the input registers.
for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
int offset =
(i * kSystemPointerSize) + FrameDescription::registers_offset();
__ pop(Operand(esi, offset));
}
int double_regs_offset = FrameDescription::double_registers_offset();
// Fill in the double input registers.
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
int dst_offset = code * kDoubleSize + double_regs_offset;
int src_offset = code * kDoubleSize;
__ movsd(xmm0, Operand(esp, src_offset));
__ movsd(Operand(esi, dst_offset), xmm0);
}
// Clear FPU all exceptions.
// TODO(ulan): Find out why the TOP register is not zero here in some cases,
// and check that the generated code never deoptimizes with unbalanced stack.
__ fnclex();
// Mark the stack as not iterable for the CPU profiler which won't be able to
// walk the stack without the return address.
__ mov_b(__ ExternalReferenceAsOperand(
ExternalReference::stack_is_iterable_address(isolate), edx),
Immediate(0));
// Remove the return address and the double registers.
__ add(esp, Immediate(kDoubleRegsSize + 1 * kSystemPointerSize));
// Compute a pointer to the unwinding limit in register ecx; that is
// the first stack slot not part of the input frame.
__ mov(ecx, Operand(esi, FrameDescription::frame_size_offset()));
__ add(ecx, esp);
// Unwind the stack down to - but not including - the unwinding
// limit and copy the contents of the activation frame to the input
// frame description.
__ lea(edx, Operand(esi, FrameDescription::frame_content_offset()));
Label pop_loop_header;
__ jmp(&pop_loop_header);
Label pop_loop;
__ bind(&pop_loop);
__ pop(Operand(edx, 0));
__ add(edx, Immediate(sizeof(uint32_t)));
__ bind(&pop_loop_header);
__ cmp(ecx, esp);
__ j(not_equal, &pop_loop);
// Compute the output frame in the deoptimizer.
__ push(eax);
__ PrepareCallCFunction(1, esi);
__ mov(Operand(esp, 0 * kSystemPointerSize), eax);
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::compute_output_frames_function(), 1);
}
__ pop(eax);
__ mov(esp, Operand(eax, Deoptimizer::caller_frame_top_offset()));
// Replace the current (input) frame with the output frames.
Label outer_push_loop, inner_push_loop, outer_loop_header, inner_loop_header;
// Outer loop state: eax = current FrameDescription**, edx = one
// past the last FrameDescription**.
__ mov(edx, Operand(eax, Deoptimizer::output_count_offset()));
__ mov(eax, Operand(eax, Deoptimizer::output_offset()));
__ lea(edx, Operand(eax, edx, times_system_pointer_size, 0));
__ jmp(&outer_loop_header);
__ bind(&outer_push_loop);
// Inner loop state: esi = current FrameDescription*, ecx = loop
// index.
__ mov(esi, Operand(eax, 0));
__ mov(ecx, Operand(esi, FrameDescription::frame_size_offset()));
__ jmp(&inner_loop_header);
__ bind(&inner_push_loop);
__ sub(ecx, Immediate(sizeof(uint32_t)));
__ push(Operand(esi, ecx, times_1, FrameDescription::frame_content_offset()));
__ bind(&inner_loop_header);
__ test(ecx, ecx);
__ j(not_zero, &inner_push_loop);
__ add(eax, Immediate(kSystemPointerSize));
__ bind(&outer_loop_header);
__ cmp(eax, edx);
__ j(below, &outer_push_loop);
// In case of a failed STUB, we have to restore the XMM registers.
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
XMMRegister xmm_reg = XMMRegister::from_code(code);
int src_offset = code * kDoubleSize + double_regs_offset;
__ movsd(xmm_reg, Operand(esi, src_offset));
}
// Push pc and continuation from the last output frame.
__ push(Operand(esi, FrameDescription::pc_offset()));
__ push(Operand(esi, FrameDescription::continuation_offset()));
// Push the registers from the last output frame.
for (int i = 0; i < kNumberOfRegisters; i++) {
int offset =
(i * kSystemPointerSize) + FrameDescription::registers_offset();
__ push(Operand(esi, offset));
}
__ mov_b(__ ExternalReferenceAsOperand(
ExternalReference::stack_is_iterable_address(isolate), edx),
Immediate(1));
// Restore the registers from the stack.
__ popad();
__ InitializeRootRegister();
// Return to the continuation point.
__ ret(0);
}
} // namespace
void Builtins::Generate_DeoptimizationEntry_Eager(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kEager);
}
void Builtins::Generate_DeoptimizationEntry_Soft(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kSoft);
}
void Builtins::Generate_DeoptimizationEntry_Bailout(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kBailout);
}
void Builtins::Generate_DeoptimizationEntry_Lazy(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kLazy);
}
#undef __
} // namespace internal

View File

@ -4101,6 +4101,223 @@ void Builtins::Generate_DirectCEntry(MacroAssembler* masm) {
__ int3(); // Unused on this architecture.
}
namespace {
void Generate_DeoptimizationEntry(MacroAssembler* masm,
DeoptimizeKind deopt_kind) {
Isolate* isolate = masm->isolate();
// Save all double registers, they will later be copied to the deoptimizer's
// FrameDescription.
static constexpr int kDoubleRegsSize =
kDoubleSize * XMMRegister::kNumRegisters;
__ AllocateStackSpace(kDoubleRegsSize);
const RegisterConfiguration* config = RegisterConfiguration::Default();
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
XMMRegister xmm_reg = XMMRegister::from_code(code);
int offset = code * kDoubleSize;
__ Movsd(Operand(rsp, offset), xmm_reg);
}
// Save all general purpose registers, they will later be copied to the
// deoptimizer's FrameDescription.
static constexpr int kNumberOfRegisters = Register::kNumRegisters;
for (int i = 0; i < kNumberOfRegisters; i++) {
__ pushq(Register::from_code(i));
}
static constexpr int kSavedRegistersAreaSize =
kNumberOfRegisters * kSystemPointerSize + kDoubleRegsSize;
static constexpr int kCurrentOffsetToReturnAddress = kSavedRegistersAreaSize;
static constexpr int kCurrentOffsetToParentSP =
kCurrentOffsetToReturnAddress + kPCOnStackSize;
__ Store(
ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate),
rbp);
// We use this to keep the value of the fifth argument temporarily.
// Unfortunately we can't store it directly in r8 (used for passing
// this on linux), since it is another parameter passing register on windows.
Register arg5 = r11;
__ movq(arg_reg_3, Immediate(Deoptimizer::kFixedExitSizeMarker));
// Get the address of the location in the code object
// and compute the fp-to-sp delta in register arg5.
__ movq(arg_reg_4, Operand(rsp, kCurrentOffsetToReturnAddress));
// Load the fp-to-sp-delta.
__ leaq(arg5, Operand(rsp, kCurrentOffsetToParentSP));
__ subq(arg5, rbp);
__ negq(arg5);
// Allocate a new deoptimizer object.
__ PrepareCallCFunction(6);
__ movq(rax, Immediate(0));
Label context_check;
__ movq(rdi, Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset));
__ JumpIfSmi(rdi, &context_check);
__ movq(rax, Operand(rbp, StandardFrameConstants::kFunctionOffset));
__ bind(&context_check);
__ movq(arg_reg_1, rax);
__ Set(arg_reg_2, static_cast<int>(deopt_kind));
// Args 3 and 4 are already in the right registers.
// On windows put the arguments on the stack (PrepareCallCFunction
// has created space for this). On linux pass the arguments in r8 and r9.
#ifdef V8_TARGET_OS_WIN
__ movq(Operand(rsp, 4 * kSystemPointerSize), arg5);
__ LoadAddress(arg5, ExternalReference::isolate_address(isolate));
__ movq(Operand(rsp, 5 * kSystemPointerSize), arg5);
#else
__ movq(r8, arg5);
__ LoadAddress(r9, ExternalReference::isolate_address(isolate));
#endif
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::new_deoptimizer_function(), 6);
}
// Preserve deoptimizer object in register rax and get the input
// frame descriptor pointer.
__ movq(rbx, Operand(rax, Deoptimizer::input_offset()));
// Fill in the input registers.
for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
int offset =
(i * kSystemPointerSize) + FrameDescription::registers_offset();
__ PopQuad(Operand(rbx, offset));
}
// Fill in the double input registers.
int double_regs_offset = FrameDescription::double_registers_offset();
for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
int dst_offset = i * kDoubleSize + double_regs_offset;
__ popq(Operand(rbx, dst_offset));
}
// Mark the stack as not iterable for the CPU profiler which won't be able to
// walk the stack without the return address.
__ movb(__ ExternalReferenceAsOperand(
ExternalReference::stack_is_iterable_address(isolate)),
Immediate(0));
// Remove the return address from the stack.
__ addq(rsp, Immediate(kPCOnStackSize));
// Compute a pointer to the unwinding limit in register rcx; that is
// the first stack slot not part of the input frame.
__ movq(rcx, Operand(rbx, FrameDescription::frame_size_offset()));
__ addq(rcx, rsp);
// Unwind the stack down to - but not including - the unwinding
// limit and copy the contents of the activation frame to the input
// frame description.
__ leaq(rdx, Operand(rbx, FrameDescription::frame_content_offset()));
Label pop_loop_header;
__ jmp(&pop_loop_header);
Label pop_loop;
__ bind(&pop_loop);
__ Pop(Operand(rdx, 0));
__ addq(rdx, Immediate(sizeof(intptr_t)));
__ bind(&pop_loop_header);
__ cmpq(rcx, rsp);
__ j(not_equal, &pop_loop);
// Compute the output frame in the deoptimizer.
__ pushq(rax);
__ PrepareCallCFunction(2);
__ movq(arg_reg_1, rax);
__ LoadAddress(arg_reg_2, ExternalReference::isolate_address(isolate));
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::compute_output_frames_function(), 2);
}
__ popq(rax);
__ movq(rsp, Operand(rax, Deoptimizer::caller_frame_top_offset()));
// Replace the current (input) frame with the output frames.
Label outer_push_loop, inner_push_loop, outer_loop_header, inner_loop_header;
// Outer loop state: rax = current FrameDescription**, rdx = one past the
// last FrameDescription**.
__ movl(rdx, Operand(rax, Deoptimizer::output_count_offset()));
__ movq(rax, Operand(rax, Deoptimizer::output_offset()));
__ leaq(rdx, Operand(rax, rdx, times_system_pointer_size, 0));
__ jmp(&outer_loop_header);
__ bind(&outer_push_loop);
// Inner loop state: rbx = current FrameDescription*, rcx = loop index.
__ movq(rbx, Operand(rax, 0));
__ movq(rcx, Operand(rbx, FrameDescription::frame_size_offset()));
__ jmp(&inner_loop_header);
__ bind(&inner_push_loop);
__ subq(rcx, Immediate(sizeof(intptr_t)));
__ Push(Operand(rbx, rcx, times_1, FrameDescription::frame_content_offset()));
__ bind(&inner_loop_header);
__ testq(rcx, rcx);
__ j(not_zero, &inner_push_loop);
__ addq(rax, Immediate(kSystemPointerSize));
__ bind(&outer_loop_header);
__ cmpq(rax, rdx);
__ j(below, &outer_push_loop);
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
XMMRegister xmm_reg = XMMRegister::from_code(code);
int src_offset = code * kDoubleSize + double_regs_offset;
__ Movsd(xmm_reg, Operand(rbx, src_offset));
}
// Push pc and continuation from the last output frame.
__ PushQuad(Operand(rbx, FrameDescription::pc_offset()));
__ PushQuad(Operand(rbx, FrameDescription::continuation_offset()));
// Push the registers from the last output frame.
for (int i = 0; i < kNumberOfRegisters; i++) {
int offset =
(i * kSystemPointerSize) + FrameDescription::registers_offset();
__ PushQuad(Operand(rbx, offset));
}
// Restore the registers from the stack.
for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
Register r = Register::from_code(i);
// Do not restore rsp, simply pop the value into the next register
// and overwrite this afterwards.
if (r == rsp) {
DCHECK_GT(i, 0);
r = Register::from_code(i - 1);
}
__ popq(r);
}
__ movb(__ ExternalReferenceAsOperand(
ExternalReference::stack_is_iterable_address(isolate)),
Immediate(1));
// Return to the continuation point.
__ ret(0);
}
} // namespace
void Builtins::Generate_DeoptimizationEntry_Eager(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kEager);
}
void Builtins::Generate_DeoptimizationEntry_Soft(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kSoft);
}
void Builtins::Generate_DeoptimizationEntry_Bailout(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kBailout);
}
void Builtins::Generate_DeoptimizationEntry_Lazy(MacroAssembler* masm) {
Generate_DeoptimizationEntry(masm, DeoptimizeKind::kLazy);
}
#undef __
} // namespace internal

View File

@ -176,8 +176,8 @@ void TurboAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode,
// size s.t. pc-relative calls may be used.
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
int offset = code->builtin_index() * kSystemPointerSize +
IsolateData::builtin_entry_table_offset();
int offset = IsolateData::builtin_entry_slot_offset(
static_cast<Builtins::Name>(code->builtin_index()));
ldr(scratch, MemOperand(kRootRegister, offset));
Jump(scratch, cond);
return;
@ -266,8 +266,8 @@ void TurboAssembler::Call(Handle<Code> code, RelocInfo::Mode rmode,
// This branch is taken only for specific cctests, where we force isolate
// creation at runtime. At this point, Code space isn't restricted to a
// size s.t. pc-relative calls may be used.
int offset = code->builtin_index() * kSystemPointerSize +
IsolateData::builtin_entry_table_offset();
int offset = IsolateData::builtin_entry_slot_offset(
static_cast<Builtins::Name>(code->builtin_index()));
ldr(ip, MemOperand(kRootRegister, offset));
Call(ip, cond);
return;
@ -2485,26 +2485,18 @@ void TurboAssembler::ResetSpeculationPoisonRegister() {
mov(kSpeculationPoisonRegister, Operand(-1));
}
void TurboAssembler::CallForDeoptimization(Address target, int deopt_id,
Label* exit, DeoptimizeKind kind) {
void TurboAssembler::CallForDeoptimization(Builtins::Name target, int,
Label* exit, DeoptimizeKind kind,
Label*) {
BlockConstPoolScope block_const_pool(this);
ldr(ip, MemOperand(kRootRegister,
IsolateData::builtin_entry_slot_offset(target)));
Call(ip);
DCHECK_EQ(SizeOfCodeGeneratedSince(exit),
(kind == DeoptimizeKind::kLazy)
? Deoptimizer::kLazyDeoptExitSize
: Deoptimizer::kNonLazyDeoptExitSize);
USE(exit, kind);
NoRootArrayScope no_root_array(this);
// Save the deopt id in r10 (we don't need the roots array from now on).
DCHECK_LE(deopt_id, 0xFFFF);
if (CpuFeatures::IsSupported(ARMv7)) {
// On ARMv7, we can use movw (with a maximum immediate of 0xFFFF)
movw(r10, deopt_id);
} else {
// On ARMv6, we might need two instructions.
mov(r10, Operand(deopt_id & 0xFF)); // Set the low byte.
if (deopt_id >= 0xFF) {
orr(r10, r10, Operand(deopt_id & 0xFF00)); // Set the high byte.
}
}
Call(target, RelocInfo::RUNTIME_ENTRY);
CheckConstPool(false, false);
}
void TurboAssembler::Trap() { stop(); }

View File

@ -320,10 +320,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// The return address on the stack is used by frame iteration.
void StoreReturnAddressAndCall(Register target);
// This should only be used when assembling a deoptimizer call because of
// the CheckConstPool invocation, which is only needed for deoptimization.
void CallForDeoptimization(Address target, int deopt_id, Label* exit,
DeoptimizeKind kind);
void CallForDeoptimization(Builtins::Name target, int deopt_id, Label* exit,
DeoptimizeKind kind,
Label* jump_deoptimization_entry_label);
// Emit code to discard a non-negative number of pointer-sized elements
// from the stack, clobbering only the sp register.

View File

@ -1878,6 +1878,13 @@ void TurboAssembler::LoadEntryFromBuiltinIndex(Register builtin_index) {
}
}
void TurboAssembler::LoadEntryFromBuiltinIndex(Builtins::Name builtin_index,
Register destination) {
Ldr(destination,
MemOperand(kRootRegister,
IsolateData::builtin_entry_slot_offset(builtin_index)));
}
void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
LoadEntryFromBuiltinIndex(builtin_index);
Call(builtin_index);
@ -2003,15 +2010,11 @@ bool TurboAssembler::IsNearCallOffset(int64_t offset) {
return is_int26(offset);
}
void TurboAssembler::CallForDeoptimization(Address target, int deopt_id,
Label* exit, DeoptimizeKind kind) {
void TurboAssembler::CallForDeoptimization(
Builtins::Name target, int deopt_id, Label* exit, DeoptimizeKind kind,
Label* jump_deoptimization_entry_label) {
BlockPoolsScope scope(this);
int64_t offset = static_cast<int64_t>(target) -
static_cast<int64_t>(options().code_range_start);
DCHECK_EQ(offset % kInstrSize, 0);
offset = offset / static_cast<int>(kInstrSize);
DCHECK(IsNearCallOffset(offset));
near_call(static_cast<int>(offset), RelocInfo::RUNTIME_ENTRY);
bl(jump_deoptimization_entry_label);
DCHECK_EQ(SizeOfCodeGeneratedSince(exit),
(kind == DeoptimizeKind::kLazy)
? Deoptimizer::kLazyDeoptExitSize

View File

@ -968,6 +968,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// Load the builtin given by the Smi in |builtin_index| into the same
// register.
void LoadEntryFromBuiltinIndex(Register builtin_index);
void LoadEntryFromBuiltinIndex(Builtins::Name builtin_index,
Register destination);
void CallBuiltinByIndex(Register builtin_index) override;
void CallBuiltin(int builtin_index);
@ -980,8 +982,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// The return address on the stack is used by frame iteration.
void StoreReturnAddressAndCall(Register target);
void CallForDeoptimization(Address target, int deopt_id, Label* exit,
DeoptimizeKind kind);
void CallForDeoptimization(Builtins::Name target, int deopt_id, Label* exit,
DeoptimizeKind kind,
Label* jump_deoptimization_entry_label);
// Calls a C function.
// The called function is not allowed to trigger a

View File

@ -2131,13 +2131,15 @@ void TurboAssembler::ComputeCodeStartAddress(Register dst) {
}
}
void TurboAssembler::CallForDeoptimization(Address target, int deopt_id,
Label* exit, DeoptimizeKind kind) {
void TurboAssembler::CallForDeoptimization(Builtins::Name target, int,
Label* exit, DeoptimizeKind kind,
Label*) {
CallBuiltin(target);
DCHECK_EQ(SizeOfCodeGeneratedSince(exit),
(kind == DeoptimizeKind::kLazy)
? Deoptimizer::kLazyDeoptExitSize
: Deoptimizer::kNonLazyDeoptExitSize);
USE(exit, kind);
NoRootArrayScope no_root_array(this);
// Save the deopt id in ebx (we don't need the roots array from now on).
mov(ebx, deopt_id);
call(target, RelocInfo::RUNTIME_ENTRY);
}
void TurboAssembler::Trap() { int3(); }

View File

@ -130,8 +130,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void Trap() override;
void DebugBreak() override;
void CallForDeoptimization(Address target, int deopt_id, Label* exit,
DeoptimizeKind kind);
void CallForDeoptimization(Builtins::Name target, int deopt_id, Label* exit,
DeoptimizeKind kind,
Label* jump_deoptimization_entry_label);
// Jump the register contains a smi.
inline void JumpIfSmi(Register value, Label* smi_label,

View File

@ -593,6 +593,12 @@ using DummyDescriptor = VoidDescriptor;
// Dummy descriptor that marks builtins with C calling convention.
using CCallDescriptor = VoidDescriptor;
// Marks deoptimization entry builtins. Precise calling conventions currently
// differ based on the platform.
// TODO(jgruber): Once this is unified, we could create a better description
// here.
using DeoptimizationEntryDescriptor = VoidDescriptor;
class AllocateDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kRequestedSize)

View File

@ -99,7 +99,7 @@ void OptimizedCompilationInfo::ConfigureFlags() {
if (FLAG_turbo_splitting) set_splitting();
break;
case CodeKind::BUILTIN:
case CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING:
case CodeKind::FOR_TESTING:
if (FLAG_turbo_splitting) set_splitting();
#if ENABLE_GDB_JIT_INTERFACE && DEBUG
set_source_positions();
@ -161,7 +161,7 @@ std::unique_ptr<char[]> OptimizedCompilationInfo::GetDebugName() const {
StackFrame::Type OptimizedCompilationInfo::GetOutputStackFrameType() const {
switch (code_kind()) {
case CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING:
case CodeKind::FOR_TESTING:
case CodeKind::BYTECODE_HANDLER:
case CodeKind::BUILTIN:
return StackFrame::STUB;

View File

@ -150,9 +150,6 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final {
return code_kind() == CodeKind::NATIVE_CONTEXT_INDEPENDENT;
}
bool IsTurboprop() const { return code_kind() == CodeKind::TURBOPROP; }
bool IsStub() const {
return code_kind() == CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING;
}
bool IsWasm() const { return code_kind() == CodeKind::WASM_FUNCTION; }
void SetOptimizingForOsr(BailoutId osr_offset, JavaScriptFrame* osr_frame) {

View File

@ -476,7 +476,7 @@ void RelocInfo::Print(Isolate* isolate, std::ostream& os) { // NOLINT
os << " " << Builtins::name(code.builtin_index());
}
os << ") (" << reinterpret_cast<const void*>(target_address()) << ")";
} else if (IsRuntimeEntry(rmode_) && isolate->deoptimizer_data() != nullptr) {
} else if (IsRuntimeEntry(rmode_)) {
// Deoptimization bailouts are stored as runtime entries.
DeoptimizeKind type;
if (Deoptimizer::IsDeoptimizationEntry(isolate, target_address(), &type)) {

View File

@ -1589,6 +1589,13 @@ void TurboAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
call(code_object, rmode);
}
Operand TurboAssembler::EntryFromBuiltinIndexAsOperand(
Builtins::Name builtin_index) {
DCHECK(root_array_available());
return Operand(kRootRegister,
IsolateData::builtin_entry_slot_offset(builtin_index));
}
Operand TurboAssembler::EntryFromBuiltinIndexAsOperand(Register builtin_index) {
if (SmiValuesAre32Bits()) {
// The builtin_index register contains the builtin index as a Smi.
@ -2825,13 +2832,18 @@ void TurboAssembler::ResetSpeculationPoisonRegister() {
Set(kSpeculationPoisonRegister, -1);
}
void TurboAssembler::CallForDeoptimization(Address target, int deopt_id,
Label* exit, DeoptimizeKind kind) {
void TurboAssembler::CallForDeoptimization(Builtins::Name target, int,
Label* exit, DeoptimizeKind kind,
Label*) {
// Note: Assembler::call is used here on purpose to guarantee fixed-size
// exits even on Atom CPUs; see TurboAssembler::Call for Atom-specific
// performance tuning which emits a different instruction sequence.
call(EntryFromBuiltinIndexAsOperand(target));
DCHECK_EQ(SizeOfCodeGeneratedSince(exit),
(kind == DeoptimizeKind::kLazy)
? Deoptimizer::kLazyDeoptExitSize
: Deoptimizer::kNonLazyDeoptExitSize);
USE(exit, kind);
NoRootArrayScope no_root_array(this);
// Save the deopt id in r13 (we don't need the roots array from now on).
movq(r13, Immediate(deopt_id));
call(target, RelocInfo::RUNTIME_ENTRY);
}
void TurboAssembler::Trap() { int3(); }

View File

@ -492,6 +492,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void Call(ExternalReference ext);
void Call(Label* target) { call(target); }
Operand EntryFromBuiltinIndexAsOperand(Builtins::Name builtin_index);
Operand EntryFromBuiltinIndexAsOperand(Register builtin_index);
void CallBuiltinByIndex(Register builtin_index) override;
void CallBuiltin(int builtin_index);
@ -511,8 +512,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void RetpolineJump(Register reg);
void CallForDeoptimization(Address target, int deopt_id, Label* exit,
DeoptimizeKind kind);
void CallForDeoptimization(Builtins::Name target, int deopt_id, Label* exit,
DeoptimizeKind kind,
Label* jump_deoptimization_entry_label);
void Trap() override;
void DebugBreak() override;

View File

@ -471,8 +471,11 @@ enum class DeoptimizeKind : uint8_t {
kSoft,
kBailout,
kLazy,
kLastDeoptimizeKind = kLazy
};
constexpr DeoptimizeKind kFirstDeoptimizeKind = DeoptimizeKind::kEager;
constexpr DeoptimizeKind kLastDeoptimizeKind = DeoptimizeKind::kLazy;
STATIC_ASSERT(static_cast<int>(kFirstDeoptimizeKind) == 0);
constexpr int kDeoptimizeKindCount = static_cast<int>(kLastDeoptimizeKind) + 1;
inline size_t hash_value(DeoptimizeKind kind) {
return static_cast<size_t>(kind);
}
@ -487,7 +490,6 @@ inline std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) {
case DeoptimizeKind::kBailout:
return os << "Bailout";
}
UNREACHABLE();
}
// Indicates whether the lookup is related to sloppy-mode block-scoped

View File

@ -962,9 +962,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDeoptimize: {
DeoptimizationExit* exit =
BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
CodeGenResult result = AssembleDeoptimizerCall(exit);
if (result != kSuccess) return result;
unwinding_info_writer_.MarkBlockWillExit();
__ b(exit->label());
break;
}
case kArchRet:
@ -3817,7 +3815,10 @@ void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
void CodeGenerator::FinishCode() { __ CheckConstPool(true, false); }
void CodeGenerator::PrepareForDeoptimizationExits(int deopt_count) {}
void CodeGenerator::PrepareForDeoptimizationExits(
ZoneDeque<DeoptimizationExit*>* exits) {
__ CheckConstPool(true, false);
}
void CodeGenerator::AssembleMove(InstructionOperand* source,
InstructionOperand* destination) {

View File

@ -3135,13 +3135,35 @@ void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
void CodeGenerator::FinishCode() { __ ForceConstantPoolEmissionWithoutJump(); }
void CodeGenerator::PrepareForDeoptimizationExits(int deopt_count) {
void CodeGenerator::PrepareForDeoptimizationExits(
ZoneDeque<DeoptimizationExit*>* exits) {
__ ForceConstantPoolEmissionWithoutJump();
// We are conservative here, assuming all deopts are lazy deopts.
DCHECK_GE(Deoptimizer::kLazyDeoptExitSize,
Deoptimizer::kNonLazyDeoptExitSize);
__ CheckVeneerPool(false, false,
deopt_count * Deoptimizer::kLazyDeoptExitSize);
__ CheckVeneerPool(
false, false,
static_cast<int>(exits->size()) * Deoptimizer::kLazyDeoptExitSize);
// Check which deopt kinds exist in this Code object, to avoid emitting jumps
// to unused entries.
bool saw_deopt_kind[kDeoptimizeKindCount] = {false};
for (auto exit : *exits) {
saw_deopt_kind[static_cast<int>(exit->kind())] = true;
}
// Emit the jumps to deoptimization entries.
UseScratchRegisterScope scope(tasm());
Register scratch = scope.AcquireX();
STATIC_ASSERT(static_cast<int>(kFirstDeoptimizeKind) == 0);
for (int i = 0; i < kDeoptimizeKindCount; i++) {
if (!saw_deopt_kind[i]) continue;
__ bind(&jump_deoptimization_entry_labels_[i]);
__ LoadEntryFromBuiltinIndex(Deoptimizer::GetDeoptimizationEntry(
isolate(), static_cast<DeoptimizeKind>(i)),
scratch);
__ Jump(scratch);
}
}
void CodeGenerator::AssembleMove(InstructionOperand* source,

View File

@ -162,8 +162,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
DeoptimizeKind deopt_kind = exit->kind();
DeoptimizeReason deoptimization_reason = exit->reason();
Address deopt_entry =
Builtins::Name deopt_entry =
Deoptimizer::GetDeoptimizationEntry(tasm()->isolate(), deopt_kind);
Label* jump_deoptimization_entry_label =
&jump_deoptimization_entry_labels_[static_cast<int>(deopt_kind)];
if (info()->source_positions()) {
tasm()->RecordDeoptReason(deoptimization_reason, exit->pos(),
deoptimization_id);
@ -177,7 +179,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
}
tasm()->CallForDeoptimization(deopt_entry, deoptimization_id, exit->label(),
deopt_kind);
deopt_kind, jump_deoptimization_entry_label);
exit->set_emitted();
return kSuccess;
}
@ -324,7 +326,7 @@ void CodeGenerator::AssembleCode() {
// For some targets, we must make sure that constant and veneer pools are
// emitted before emitting the deoptimization exits.
PrepareForDeoptimizationExits(static_cast<int>(deoptimization_exits_.size()));
PrepareForDeoptimizationExits(&deoptimization_exits_);
if (Deoptimizer::kSupportsFixedDeoptExitSizes) {
deopt_exit_start_offset_ = tasm()->pc_offset();
@ -338,7 +340,7 @@ void CodeGenerator::AssembleCode() {
// Deoptimizer::kSupportsFixedDeoptExitSizes is true, lazy deopts
// might need additional instructions.
auto cmp = [](const DeoptimizationExit* a, const DeoptimizationExit* b) {
static_assert(DeoptimizeKind::kLazy == DeoptimizeKind::kLastDeoptimizeKind,
static_assert(DeoptimizeKind::kLazy == kLastDeoptimizeKind,
"lazy deopts are expected to be emitted last");
if (a->kind() != b->kind()) {
return a->kind() < b->kind();

View File

@ -406,7 +406,7 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler {
InstructionOperand* op, MachineType type);
void MarkLazyDeoptSite();
void PrepareForDeoptimizationExits(int deopt_count);
void PrepareForDeoptimizationExits(ZoneDeque<DeoptimizationExit*>* exits);
DeoptimizationExit* AddDeoptimizationExit(Instruction* instr,
size_t frame_state_offset);
@ -446,6 +446,14 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler {
int handler_table_offset_ = 0;
int last_lazy_deopt_pc_ = 0;
// Deoptimization exits must be as small as possible, since their count grows
// with function size. {jump_deoptimization_entry_labels_} is an optimization
// to that effect, which extracts the (potentially large) instruction
// sequence for the final jump to the deoptimization entry into a single spot
// per Code object. All deopt exits can then near-call to this label. Note:
// not used on all architectures.
Label jump_deoptimization_entry_labels_[kDeoptimizeKindCount];
// The maximal combined height of all frames produced upon deoptimization, and
// the maximal number of pushed arguments for function calls. Applied as an
// offset to the first stack check of an optimized function.

View File

@ -927,8 +927,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDeoptimize: {
DeoptimizationExit* exit =
BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
CodeGenResult result = AssembleDeoptimizerCall(exit);
if (result != kSuccess) return result;
__ jmp(exit->label());
break;
}
case kArchRet:
@ -4893,7 +4892,8 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
void CodeGenerator::FinishCode() {}
void CodeGenerator::PrepareForDeoptimizationExits(int deopt_count) {}
void CodeGenerator::PrepareForDeoptimizationExits(
ZoneDeque<DeoptimizationExit*>* exits) {}
void CodeGenerator::AssembleMove(InstructionOperand* source,
InstructionOperand* destination) {

View File

@ -1099,9 +1099,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDeoptimize: {
DeoptimizationExit* exit =
BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
CodeGenResult result = AssembleDeoptimizerCall(exit);
if (result != kSuccess) return result;
unwinding_info_writer_.MarkBlockWillExit();
__ jmp(exit->label());
break;
}
case kArchRet:
@ -4579,7 +4577,8 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
void CodeGenerator::FinishCode() { tasm()->PatchConstPool(); }
void CodeGenerator::PrepareForDeoptimizationExits(int deopt_count) {}
void CodeGenerator::PrepareForDeoptimizationExits(
ZoneDeque<DeoptimizationExit*>* exits) {}
void CodeGenerator::IncrementStackAccessCounter(
InstructionOperand* source, InstructionOperand* destination) {

View File

@ -1164,11 +1164,6 @@ PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl(
if (compilation_info()->is_osr()) data_.InitializeOsrHelper();
// Make sure that we have generated the deopt entries code. This is in order
// to avoid triggering the generation of deopt entries later during code
// assembly.
Deoptimizer::EnsureCodeForDeoptimizationEntries(isolate);
pipeline_.Serialize();
if (!data_.broker()->is_concurrent_inlining()) {
@ -3011,7 +3006,6 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
PipelineImpl pipeline(&data);
Linkage linkage(Linkage::ComputeIncoming(data.instruction_zone(), info));
Deoptimizer::EnsureCodeForDeoptimizationEntries(isolate);
{
CompilationHandleScope compilation_scope(isolate, info);
@ -3236,7 +3230,7 @@ bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
bool use_mid_tier_register_allocator,
bool run_verifier) {
OptimizedCompilationInfo info(ArrayVector("testing"), sequence->zone(),
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING);
CodeKind::FOR_TESTING);
ZoneStats zone_stats(sequence->isolate()->allocator());
PipelineData data(&zone_stats, &info, sequence->isolate(), sequence);
data.InitializeFrameData(nullptr);

View File

@ -2,246 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/codegen/register-configuration.h"
#include "src/codegen/safepoint-table.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/objects/objects-inl.h"
namespace v8 {
namespace internal {
const bool Deoptimizer::kSupportsFixedDeoptExitSizes = false;
const int Deoptimizer::kNonLazyDeoptExitSize = 0;
const int Deoptimizer::kLazyDeoptExitSize = 0;
#define __ masm->
// This code tries to be close to ia32 code so that any changes can be
// easily ported.
void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
Isolate* isolate,
DeoptimizeKind deopt_kind) {
NoRootArrayScope no_root_array(masm);
// Save all general purpose registers before messing with them.
const int kNumberOfRegisters = Register::kNumRegisters;
// Everything but pc, lr and ip which will be saved but not restored.
RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit();
const int kDoubleRegsSize = kDoubleSize * DwVfpRegister::kNumRegisters;
// Save all allocatable VFP registers before messing with them.
{
// We use a run-time check for VFP32DREGS.
CpuFeatureScope scope(masm, VFP32DREGS,
CpuFeatureScope::kDontCheckSupported);
UseScratchRegisterScope temps(masm);
Register scratch = temps.Acquire();
// Check CPU flags for number of registers, setting the Z condition flag.
__ CheckFor32DRegs(scratch);
// Push registers d0-d15, and possibly d16-d31, on the stack.
// If d16-d31 are not pushed, decrease the stack pointer instead.
__ vstm(db_w, sp, d16, d31, ne);
// Okay to not call AllocateStackSpace here because the size is a known
// small number and we need to use condition codes.
__ sub(sp, sp, Operand(16 * kDoubleSize), LeaveCC, eq);
__ vstm(db_w, sp, d0, d15);
}
// Push all 16 registers (needed to populate FrameDescription::registers_).
// TODO(1588) Note that using pc with stm is deprecated, so we should perhaps
// handle this a bit differently.
__ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit());
{
UseScratchRegisterScope temps(masm);
Register scratch = temps.Acquire();
__ mov(scratch, Operand(ExternalReference::Create(
IsolateAddressId::kCEntryFPAddress, isolate)));
__ str(fp, MemOperand(scratch));
}
const int kSavedRegistersAreaSize =
(kNumberOfRegisters * kPointerSize) + kDoubleRegsSize;
// Get the bailout id is passed as r10 by the caller.
__ mov(r2, r10);
// Get the address of the location in the code object (r3) (return
// address for lazy deoptimization) and compute the fp-to-sp delta in
// register r4.
__ mov(r3, lr);
__ add(r4, sp, Operand(kSavedRegistersAreaSize));
__ sub(r4, fp, r4);
// Allocate a new deoptimizer object.
// Pass four arguments in r0 to r3 and fifth argument on stack.
__ PrepareCallCFunction(6);
__ mov(r0, Operand(0));
Label context_check;
__ ldr(r1, MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset));
__ JumpIfSmi(r1, &context_check);
__ ldr(r0, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ bind(&context_check);
__ mov(r1, Operand(static_cast<int>(deopt_kind)));
// r2: bailout id already loaded.
// r3: code address or 0 already loaded.
__ str(r4, MemOperand(sp, 0 * kPointerSize)); // Fp-to-sp delta.
__ mov(r5, Operand(ExternalReference::isolate_address(isolate)));
__ str(r5, MemOperand(sp, 1 * kPointerSize)); // Isolate.
// Call Deoptimizer::New().
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::new_deoptimizer_function(), 6);
}
// Preserve "deoptimizer" object in register r0 and get the input
// frame descriptor pointer to r1 (deoptimizer->input_);
__ ldr(r1, MemOperand(r0, Deoptimizer::input_offset()));
// Copy core registers into FrameDescription::registers_[kNumRegisters].
DCHECK_EQ(Register::kNumRegisters, kNumberOfRegisters);
for (int i = 0; i < kNumberOfRegisters; i++) {
int offset = (i * kPointerSize) + FrameDescription::registers_offset();
__ ldr(r2, MemOperand(sp, i * kPointerSize));
__ str(r2, MemOperand(r1, offset));
}
// Copy VFP registers to
// double_registers_[DoubleRegister::kNumAllocatableRegisters]
int double_regs_offset = FrameDescription::double_registers_offset();
const RegisterConfiguration* config = RegisterConfiguration::Default();
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
int dst_offset = code * kDoubleSize + double_regs_offset;
int src_offset = code * kDoubleSize + kNumberOfRegisters * kPointerSize;
__ vldr(d0, sp, src_offset);
__ vstr(d0, r1, dst_offset);
}
// Mark the stack as not iterable for the CPU profiler which won't be able to
// walk the stack without the return address.
{
UseScratchRegisterScope temps(masm);
Register is_iterable = temps.Acquire();
Register zero = r4;
__ Move(is_iterable, ExternalReference::stack_is_iterable_address(isolate));
__ mov(zero, Operand(0));
__ strb(zero, MemOperand(is_iterable));
}
// Remove the saved registers from the stack.
__ add(sp, sp, Operand(kSavedRegistersAreaSize));
// Compute a pointer to the unwinding limit in register r2; that is
// the first stack slot not part of the input frame.
__ ldr(r2, MemOperand(r1, FrameDescription::frame_size_offset()));
__ add(r2, r2, sp);
// Unwind the stack down to - but not including - the unwinding
// limit and copy the contents of the activation frame to the input
// frame description.
__ add(r3, r1, Operand(FrameDescription::frame_content_offset()));
Label pop_loop;
Label pop_loop_header;
__ b(&pop_loop_header);
__ bind(&pop_loop);
__ pop(r4);
__ str(r4, MemOperand(r3, 0));
__ add(r3, r3, Operand(sizeof(uint32_t)));
__ bind(&pop_loop_header);
__ cmp(r2, sp);
__ b(ne, &pop_loop);
// Compute the output frame in the deoptimizer.
__ push(r0); // Preserve deoptimizer object across call.
// r0: deoptimizer object; r1: scratch.
__ PrepareCallCFunction(1);
// Call Deoptimizer::ComputeOutputFrames().
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::compute_output_frames_function(), 1);
}
__ pop(r0); // Restore deoptimizer object (class Deoptimizer).
__ ldr(sp, MemOperand(r0, Deoptimizer::caller_frame_top_offset()));
// Replace the current (input) frame with the output frames.
Label outer_push_loop, inner_push_loop, outer_loop_header, inner_loop_header;
// Outer loop state: r4 = current "FrameDescription** output_",
// r1 = one past the last FrameDescription**.
__ ldr(r1, MemOperand(r0, Deoptimizer::output_count_offset()));
__ ldr(r4, MemOperand(r0, Deoptimizer::output_offset())); // r4 is output_.
__ add(r1, r4, Operand(r1, LSL, 2));
__ jmp(&outer_loop_header);
__ bind(&outer_push_loop);
// Inner loop state: r2 = current FrameDescription*, r3 = loop index.
__ ldr(r2, MemOperand(r4, 0)); // output_[ix]
__ ldr(r3, MemOperand(r2, FrameDescription::frame_size_offset()));
__ jmp(&inner_loop_header);
__ bind(&inner_push_loop);
__ sub(r3, r3, Operand(sizeof(uint32_t)));
__ add(r6, r2, Operand(r3));
__ ldr(r6, MemOperand(r6, FrameDescription::frame_content_offset()));
__ push(r6);
__ bind(&inner_loop_header);
__ cmp(r3, Operand::Zero());
__ b(ne, &inner_push_loop); // test for gt?
__ add(r4, r4, Operand(kPointerSize));
__ bind(&outer_loop_header);
__ cmp(r4, r1);
__ b(lt, &outer_push_loop);
__ ldr(r1, MemOperand(r0, Deoptimizer::input_offset()));
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
DwVfpRegister reg = DwVfpRegister::from_code(code);
int src_offset = code * kDoubleSize + double_regs_offset;
__ vldr(reg, r1, src_offset);
}
// Push pc and continuation from the last output frame.
__ ldr(r6, MemOperand(r2, FrameDescription::pc_offset()));
__ push(r6);
__ ldr(r6, MemOperand(r2, FrameDescription::continuation_offset()));
__ push(r6);
// Push the registers from the last output frame.
for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
int offset = (i * kPointerSize) + FrameDescription::registers_offset();
__ ldr(r6, MemOperand(r2, offset));
__ push(r6);
}
// Restore the registers from the stack.
__ ldm(ia_w, sp, restored_regs); // all but pc registers.
{
UseScratchRegisterScope temps(masm);
Register is_iterable = temps.Acquire();
Register one = r4;
__ Move(is_iterable, ExternalReference::stack_is_iterable_address(isolate));
__ mov(one, Operand(1));
__ strb(one, MemOperand(is_iterable));
}
// Remove sp, lr and pc.
__ Drop(3);
{
UseScratchRegisterScope temps(masm);
Register scratch = temps.Acquire();
__ pop(scratch); // get continuation, leave pc on stack
__ pop(lr);
__ Jump(scratch);
}
__ stop();
}
const bool Deoptimizer::kSupportsFixedDeoptExitSizes = true;
const int Deoptimizer::kNonLazyDeoptExitSize = 2 * kInstrSize;
const int Deoptimizer::kLazyDeoptExitSize = 2 * kInstrSize;
Float32 RegisterValues::GetFloatRegister(unsigned n) const {
const int kShift = n % 2 == 0 ? 0 : 32;
@ -265,7 +33,5 @@ void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
void FrameDescription::SetPc(intptr_t pc) { pc_ = pc; }
#undef __
} // namespace internal
} // namespace v8

View File

@ -3,12 +3,7 @@
// found in the LICENSE file.
#include "src/api/api.h"
#include "src/codegen/arm64/assembler-arm64-inl.h"
#include "src/codegen/arm64/macro-assembler-arm64-inl.h"
#include "src/codegen/register-configuration.h"
#include "src/codegen/safepoint-table.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/execution/frame-constants.h"
#include "src/execution/pointer-authentication.h"
namespace v8 {
@ -22,286 +17,6 @@ const int Deoptimizer::kLazyDeoptExitSize = 2 * kInstrSize;
const int Deoptimizer::kLazyDeoptExitSize = 1 * kInstrSize;
#endif
#define __ masm->
namespace {
void CopyRegListToFrame(MacroAssembler* masm, const Register& dst,
int dst_offset, const CPURegList& reg_list,
const Register& temp0, const Register& temp1,
int src_offset = 0) {
DCHECK_EQ(reg_list.Count() % 2, 0);
UseScratchRegisterScope temps(masm);
CPURegList copy_to_input = reg_list;
int reg_size = reg_list.RegisterSizeInBytes();
DCHECK_EQ(temp0.SizeInBytes(), reg_size);
DCHECK_EQ(temp1.SizeInBytes(), reg_size);
// Compute some temporary addresses to avoid having the macro assembler set
// up a temp with an offset for accesses out of the range of the addressing
// mode.
Register src = temps.AcquireX();
masm->Add(src, sp, src_offset);
masm->Add(dst, dst, dst_offset);
// Write reg_list into the frame pointed to by dst.
for (int i = 0; i < reg_list.Count(); i += 2) {
masm->Ldp(temp0, temp1, MemOperand(src, i * reg_size));
CPURegister reg0 = copy_to_input.PopLowestIndex();
CPURegister reg1 = copy_to_input.PopLowestIndex();
int offset0 = reg0.code() * reg_size;
int offset1 = reg1.code() * reg_size;
// Pair up adjacent stores, otherwise write them separately.
if (offset1 == offset0 + reg_size) {
masm->Stp(temp0, temp1, MemOperand(dst, offset0));
} else {
masm->Str(temp0, MemOperand(dst, offset0));
masm->Str(temp1, MemOperand(dst, offset1));
}
}
masm->Sub(dst, dst, dst_offset);
}
void RestoreRegList(MacroAssembler* masm, const CPURegList& reg_list,
const Register& src_base, int src_offset) {
DCHECK_EQ(reg_list.Count() % 2, 0);
UseScratchRegisterScope temps(masm);
CPURegList restore_list = reg_list;
int reg_size = restore_list.RegisterSizeInBytes();
// Compute a temporary addresses to avoid having the macro assembler set
// up a temp with an offset for accesses out of the range of the addressing
// mode.
Register src = temps.AcquireX();
masm->Add(src, src_base, src_offset);
// No need to restore padreg.
restore_list.Remove(padreg);
// Restore every register in restore_list from src.
while (!restore_list.IsEmpty()) {
CPURegister reg0 = restore_list.PopLowestIndex();
CPURegister reg1 = restore_list.PopLowestIndex();
int offset0 = reg0.code() * reg_size;
if (reg1 == NoCPUReg) {
masm->Ldr(reg0, MemOperand(src, offset0));
break;
}
int offset1 = reg1.code() * reg_size;
// Pair up adjacent loads, otherwise read them separately.
if (offset1 == offset0 + reg_size) {
masm->Ldp(reg0, reg1, MemOperand(src, offset0));
} else {
masm->Ldr(reg0, MemOperand(src, offset0));
masm->Ldr(reg1, MemOperand(src, offset1));
}
}
}
} // namespace
void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
Isolate* isolate,
DeoptimizeKind deopt_kind) {
NoRootArrayScope no_root_array(masm);
// TODO(all): This code needs to be revisited. We probably only need to save
// caller-saved registers here. Callee-saved registers can be stored directly
// in the input frame.
// Save all allocatable double registers.
CPURegList saved_double_registers(
CPURegister::kVRegister, kDRegSizeInBits,
RegisterConfiguration::Default()->allocatable_double_codes_mask());
DCHECK_EQ(saved_double_registers.Count() % 2, 0);
__ PushCPURegList(saved_double_registers);
// We save all the registers except sp, lr, platform register (x18) and the
// masm scratches.
CPURegList saved_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 28);
saved_registers.Remove(ip0);
saved_registers.Remove(ip1);
saved_registers.Remove(x18);
saved_registers.Combine(fp);
saved_registers.Align();
DCHECK_EQ(saved_registers.Count() % 2, 0);
__ PushCPURegList(saved_registers);
__ Mov(x3, Operand(ExternalReference::Create(
IsolateAddressId::kCEntryFPAddress, isolate)));
__ Str(fp, MemOperand(x3));
const int kSavedRegistersAreaSize =
(saved_registers.Count() * kXRegSize) +
(saved_double_registers.Count() * kDRegSize);
// Floating point registers are saved on the stack above core registers.
const int kDoubleRegistersOffset = saved_registers.Count() * kXRegSize;
// We don't use a bailout id for arm64, because we can compute the id from the
// address. Pass kMaxUInt32 instead to signify this.
Register bailout_id = x2;
__ Mov(bailout_id, kMaxUInt32);
Register code_object = x3;
Register fp_to_sp = x4;
// Get the address of the location in the code object. This is the return
// address for lazy deoptimization.
__ Mov(code_object, lr);
// Compute the fp-to-sp delta.
__ Add(fp_to_sp, sp, kSavedRegistersAreaSize);
__ Sub(fp_to_sp, fp, fp_to_sp);
// Allocate a new deoptimizer object.
__ Ldr(x1, MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset));
// Ensure we can safely load from below fp.
DCHECK_GT(kSavedRegistersAreaSize, -StandardFrameConstants::kFunctionOffset);
__ Ldr(x0, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
// If x1 is a smi, zero x0.
__ Tst(x1, kSmiTagMask);
__ CzeroX(x0, eq);
__ Mov(x1, static_cast<int>(deopt_kind));
// Following arguments are already loaded:
// - x2: bailout id
// - x3: code object address
// - x4: fp-to-sp delta
__ Mov(x5, ExternalReference::isolate_address(isolate));
{
// Call Deoptimizer::New().
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::new_deoptimizer_function(), 6);
}
// Preserve "deoptimizer" object in register x0.
Register deoptimizer = x0;
// Get the input frame descriptor pointer.
__ Ldr(x1, MemOperand(deoptimizer, Deoptimizer::input_offset()));
// Copy core registers into the input frame.
CopyRegListToFrame(masm, x1, FrameDescription::registers_offset(),
saved_registers, x2, x3);
// Copy double registers to the input frame.
CopyRegListToFrame(masm, x1, FrameDescription::double_registers_offset(),
saved_double_registers, x2, x3, kDoubleRegistersOffset);
// Mark the stack as not iterable for the CPU profiler which won't be able to
// walk the stack without the return address.
{
UseScratchRegisterScope temps(masm);
Register is_iterable = temps.AcquireX();
__ Mov(is_iterable, ExternalReference::stack_is_iterable_address(isolate));
__ strb(xzr, MemOperand(is_iterable));
}
// Remove the saved registers from the stack.
DCHECK_EQ(kSavedRegistersAreaSize % kXRegSize, 0);
__ Drop(kSavedRegistersAreaSize / kXRegSize);
// Compute a pointer to the unwinding limit in register x2; that is
// the first stack slot not part of the input frame.
Register unwind_limit = x2;
__ Ldr(unwind_limit, MemOperand(x1, FrameDescription::frame_size_offset()));
// Unwind the stack down to - but not including - the unwinding
// limit and copy the contents of the activation frame to the input
// frame description.
__ Add(x3, x1, FrameDescription::frame_content_offset());
__ SlotAddress(x1, 0);
__ Lsr(unwind_limit, unwind_limit, kSystemPointerSizeLog2);
__ Mov(x5, unwind_limit);
__ CopyDoubleWords(x3, x1, x5);
__ Drop(unwind_limit);
// Compute the output frame in the deoptimizer.
__ Push(padreg, x0); // Preserve deoptimizer object across call.
{
// Call Deoptimizer::ComputeOutputFrames().
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::compute_output_frames_function(), 1);
}
__ Pop(x4, padreg); // Restore deoptimizer object (class Deoptimizer).
{
UseScratchRegisterScope temps(masm);
Register scratch = temps.AcquireX();
__ Ldr(scratch, MemOperand(x4, Deoptimizer::caller_frame_top_offset()));
__ Mov(sp, scratch);
}
// Replace the current (input) frame with the output frames.
Label outer_push_loop, outer_loop_header;
__ Ldrsw(x1, MemOperand(x4, Deoptimizer::output_count_offset()));
__ Ldr(x0, MemOperand(x4, Deoptimizer::output_offset()));
__ Add(x1, x0, Operand(x1, LSL, kSystemPointerSizeLog2));
__ B(&outer_loop_header);
__ Bind(&outer_push_loop);
Register current_frame = x2;
Register frame_size = x3;
__ Ldr(current_frame, MemOperand(x0, kSystemPointerSize, PostIndex));
__ Ldr(x3, MemOperand(current_frame, FrameDescription::frame_size_offset()));
__ Lsr(frame_size, x3, kSystemPointerSizeLog2);
__ Claim(frame_size);
__ Add(x7, current_frame, FrameDescription::frame_content_offset());
__ SlotAddress(x6, 0);
__ CopyDoubleWords(x6, x7, frame_size);
__ Bind(&outer_loop_header);
__ Cmp(x0, x1);
__ B(lt, &outer_push_loop);
__ Ldr(x1, MemOperand(x4, Deoptimizer::input_offset()));
RestoreRegList(masm, saved_double_registers, x1,
FrameDescription::double_registers_offset());
{
UseScratchRegisterScope temps(masm);
Register is_iterable = temps.AcquireX();
Register one = x4;
__ Mov(is_iterable, ExternalReference::stack_is_iterable_address(isolate));
__ Mov(one, Operand(1));
__ strb(one, MemOperand(is_iterable));
}
// TODO(all): ARM copies a lot (if not all) of the last output frame onto the
// stack, then pops it all into registers. Here, we try to load it directly
// into the relevant registers. Is this correct? If so, we should improve the
// ARM code.
// Restore registers from the last output frame.
// Note that lr is not in the list of saved_registers and will be restored
// later. We can use it to hold the address of last output frame while
// reloading the other registers.
DCHECK(!saved_registers.IncludesAliasOf(lr));
Register last_output_frame = lr;
__ Mov(last_output_frame, current_frame);
RestoreRegList(masm, saved_registers, last_output_frame,
FrameDescription::registers_offset());
UseScratchRegisterScope temps(masm);
temps.Exclude(x17);
Register continuation = x17;
__ Ldr(continuation, MemOperand(last_output_frame,
FrameDescription::continuation_offset()));
__ Ldr(lr, MemOperand(last_output_frame, FrameDescription::pc_offset()));
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
__ Autibsp();
#endif
__ Br(continuation);
}
Float32 RegisterValues::GetFloatRegister(unsigned n) const {
return Float32::FromBits(
static_cast<uint32_t>(double_registers_[n].get_bits()));
@ -331,7 +46,5 @@ void FrameDescription::SetPc(intptr_t pc) {
pc_ = pc;
}
#undef __
} // namespace internal
} // namespace v8

View File

@ -26,6 +26,7 @@
#include "src/objects/debug-objects-inl.h"
#include "src/objects/heap-number-inl.h"
#include "src/objects/smi.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/tracing/trace-event.h"
#include "torque-generated/exported-class-definitions.h"
@ -173,25 +174,6 @@ class FrameWriter {
unsigned top_offset_;
};
DeoptimizerData::DeoptimizerData(Heap* heap) : heap_(heap), current_(nullptr) {
Code* start = &deopt_entry_code_[0];
Code* end = &deopt_entry_code_[DeoptimizerData::kLastDeoptimizeKind + 1];
strong_roots_entry_ =
heap_->RegisterStrongRoots(FullObjectSlot(start), FullObjectSlot(end));
}
DeoptimizerData::~DeoptimizerData() {
heap_->UnregisterStrongRoots(strong_roots_entry_);
}
Code DeoptimizerData::deopt_entry_code(DeoptimizeKind kind) {
return deopt_entry_code_[static_cast<int>(kind)];
}
void DeoptimizerData::set_deopt_entry_code(DeoptimizeKind kind, Code code) {
deopt_entry_code_[static_cast<int>(kind)] = code;
}
Code Deoptimizer::FindDeoptimizingCode(Address addr) {
if (function_.IsHeapObject()) {
// Search all deoptimizing code in the native context of the function.
@ -208,7 +190,7 @@ Code Deoptimizer::FindDeoptimizingCode(Address addr) {
return Code();
}
// We rely on this function not causing a GC. It is called from generated code
// We rely on this function not causing a GC. It is called from generated code
// without having a real stack frame in place.
Deoptimizer* Deoptimizer::New(Address raw_function, DeoptimizeKind kind,
unsigned bailout_id, Address from,
@ -216,16 +198,13 @@ Deoptimizer* Deoptimizer::New(Address raw_function, DeoptimizeKind kind,
JSFunction function = JSFunction::cast(Object(raw_function));
Deoptimizer* deoptimizer = new Deoptimizer(isolate, function, kind,
bailout_id, from, fp_to_sp_delta);
CHECK_NULL(isolate->deoptimizer_data()->current_);
isolate->deoptimizer_data()->current_ = deoptimizer;
isolate->set_current_deoptimizer(deoptimizer);
return deoptimizer;
}
Deoptimizer* Deoptimizer::Grab(Isolate* isolate) {
Deoptimizer* result = isolate->deoptimizer_data()->current_;
CHECK_NOT_NULL(result);
Deoptimizer* result = isolate->GetAndClearCurrentDeoptimizer();
result->DeleteFrameDescriptions();
isolate->deoptimizer_data()->current_ = nullptr;
return result;
}
@ -492,8 +471,6 @@ const char* Deoptimizer::MessageFor(DeoptimizeKind kind, bool reuse_code) {
case DeoptimizeKind::kBailout:
return "bailout";
}
FATAL("Unsupported deopt kind");
return nullptr;
}
namespace {
@ -536,6 +513,9 @@ Deoptimizer::Deoptimizer(Isolate* isolate, JSFunction function,
deoptimizing_throw_ = true;
}
DCHECK(bailout_id_ == kFixedExitSizeMarker ||
bailout_id_ < kMaxNumberOfEntries);
DCHECK_NE(from, kNullAddress);
compiled_code_ = FindOptimizedCode();
DCHECK(!compiled_code_.is_null());
@ -564,7 +544,7 @@ Deoptimizer::Deoptimizer(Isolate* isolate, JSFunction function,
input_ = new (size) FrameDescription(size, parameter_count);
if (kSupportsFixedDeoptExitSizes) {
DCHECK_EQ(bailout_id_, kMaxUInt32);
DCHECK_EQ(bailout_id_, kFixedExitSizeMarker);
// Calculate bailout id from return address.
DCHECK_GT(kNonLazyDeoptExitSize, 0);
DCHECK_GT(kLazyDeoptExitSize, 0);
@ -576,7 +556,7 @@ Deoptimizer::Deoptimizer(Isolate* isolate, JSFunction function,
Address lazy_deopt_start =
deopt_start + non_lazy_deopt_count * kNonLazyDeoptExitSize;
// The deoptimization exits are sorted so that lazy deopt exits appear last.
static_assert(DeoptimizeKind::kLazy == DeoptimizeKind::kLastDeoptimizeKind,
static_assert(DeoptimizeKind::kLazy == kLastDeoptimizeKind,
"lazy deopts are expected to be emitted last");
// from_ is the value of the link register after the call to the
// deoptimizer, so for the last lazy deopt, from_ points to the first
@ -635,42 +615,44 @@ void Deoptimizer::DeleteFrameDescriptions() {
#endif // DEBUG
}
Address Deoptimizer::GetDeoptimizationEntry(Isolate* isolate,
DeoptimizeKind kind) {
DeoptimizerData* data = isolate->deoptimizer_data();
CHECK_LE(kind, DeoptimizerData::kLastDeoptimizeKind);
CHECK(!data->deopt_entry_code(kind).is_null());
return data->deopt_entry_code(kind).raw_instruction_start();
Builtins::Name Deoptimizer::GetDeoptimizationEntry(Isolate* isolate,
DeoptimizeKind kind) {
switch (kind) {
case DeoptimizeKind::kEager:
return Builtins::kDeoptimizationEntry_Eager;
case DeoptimizeKind::kSoft:
return Builtins::kDeoptimizationEntry_Soft;
case DeoptimizeKind::kBailout:
return Builtins::kDeoptimizationEntry_Bailout;
case DeoptimizeKind::kLazy:
return Builtins::kDeoptimizationEntry_Lazy;
}
}
bool Deoptimizer::IsDeoptimizationEntry(Isolate* isolate, Address addr,
DeoptimizeKind type) {
DeoptimizerData* data = isolate->deoptimizer_data();
CHECK_LE(type, DeoptimizerData::kLastDeoptimizeKind);
Code code = data->deopt_entry_code(type);
if (code.is_null()) return false;
return addr == code.raw_instruction_start();
}
DeoptimizeKind* type_out) {
Code maybe_code = InstructionStream::TryLookupCode(isolate, addr);
if (maybe_code.is_null()) return false;
bool Deoptimizer::IsDeoptimizationEntry(Isolate* isolate, Address addr,
DeoptimizeKind* type) {
if (IsDeoptimizationEntry(isolate, addr, DeoptimizeKind::kEager)) {
*type = DeoptimizeKind::kEager;
return true;
Code code = maybe_code;
switch (code.builtin_index()) {
case Builtins::kDeoptimizationEntry_Eager:
*type_out = DeoptimizeKind::kEager;
return true;
case Builtins::kDeoptimizationEntry_Soft:
*type_out = DeoptimizeKind::kSoft;
return true;
case Builtins::kDeoptimizationEntry_Bailout:
*type_out = DeoptimizeKind::kBailout;
return true;
case Builtins::kDeoptimizationEntry_Lazy:
*type_out = DeoptimizeKind::kLazy;
return true;
default:
return false;
}
if (IsDeoptimizationEntry(isolate, addr, DeoptimizeKind::kSoft)) {
*type = DeoptimizeKind::kSoft;
return true;
}
if (IsDeoptimizationEntry(isolate, addr, DeoptimizeKind::kLazy)) {
*type = DeoptimizeKind::kLazy;
return true;
}
if (IsDeoptimizationEntry(isolate, addr, DeoptimizeKind::kBailout)) {
*type = DeoptimizeKind::kBailout;
return true;
}
return false;
UNREACHABLE();
}
int Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) {
@ -818,8 +800,8 @@ void Deoptimizer::TraceDeoptMarked(Isolate* isolate) {
// without having a real stack frame in place.
void Deoptimizer::DoComputeOutputFrames() {
// When we call this function, the return address of the previous frame has
// been removed from the stack by GenerateDeoptimizationEntries() so the stack
// is not iterable by the SafeStackFrameIterator.
// been removed from the stack by the DeoptimizationEntry builtin, so the
// stack is not iterable by the SafeStackFrameIterator.
#if V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK
DCHECK_EQ(0, isolate()->isolate_data()->stack_is_iterable());
#endif
@ -881,7 +863,7 @@ void Deoptimizer::DoComputeOutputFrames() {
// Do the input frame to output frame(s) translation.
size_t count = translated_state_.frames().size();
// If we are supposed to go to the catch handler, find the catching frame
// for the catch and make sure we only deoptimize upto that frame.
// for the catch and make sure we only deoptimize up to that frame.
if (deoptimizing_throw_) {
size_t catch_handler_frame_index = count;
for (size_t i = count; i-- > 0;) {
@ -1212,7 +1194,7 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
: builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
if (is_topmost) {
// Only the pc of the topmost frame needs to be signed since it is
// authenticated at the end of GenerateDeoptimizationEntries.
// authenticated at the end of the DeoptimizationEntry builtin.
const intptr_t top_most_pc = PointerAuthentication::SignAndCheckPC(
static_cast<intptr_t>(dispatch_builtin.InstructionStart()),
frame_writer.frame()->GetTop());
@ -1539,7 +1521,7 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
intptr_t pc_value = static_cast<intptr_t>(start + pc_offset);
if (is_topmost) {
// Only the pc of the topmost frame needs to be signed since it is
// authenticated at the end of GenerateDeoptimizationEntries.
// authenticated at the end of the DeoptimizationEntry builtin.
output_frame->SetPc(PointerAuthentication::SignAndCheckPC(
pc_value, frame_writer.frame()->GetTop()));
} else {
@ -1940,7 +1922,7 @@ void Deoptimizer::DoComputeBuiltinContinuation(
mode, frame_info.frame_has_result_stack_slot()));
if (is_topmost) {
// Only the pc of the topmost frame needs to be signed since it is
// authenticated at the end of GenerateDeoptimizationEntries.
// authenticated at the end of the DeoptimizationEntry builtin.
const intptr_t top_most_pc = PointerAuthentication::SignAndCheckPC(
static_cast<intptr_t>(continue_to_builtin.InstructionStart()),
frame_writer.frame()->GetTop());
@ -2037,40 +2019,6 @@ unsigned Deoptimizer::ComputeIncomingArgumentSize(SharedFunctionInfo shared) {
return parameter_slots * kSystemPointerSize;
}
void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
DeoptimizeKind kind) {
CHECK(kind == DeoptimizeKind::kEager || kind == DeoptimizeKind::kSoft ||
kind == DeoptimizeKind::kLazy || kind == DeoptimizeKind::kBailout);
DeoptimizerData* data = isolate->deoptimizer_data();
if (!data->deopt_entry_code(kind).is_null()) return;
MacroAssembler masm(isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(16 * KB));
masm.set_emit_debug_code(false);
GenerateDeoptimizationEntries(&masm, masm.isolate(), kind);
CodeDesc desc;
masm.GetCode(isolate, &desc);
DCHECK(!RelocInfo::RequiresRelocationAfterCodegen(desc));
// Allocate the code as immovable since the entry addresses will be used
// directly and there is no support for relocating them.
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.set_immovable()
.Build();
CHECK(isolate->heap()->IsImmovable(*code));
CHECK(data->deopt_entry_code(kind).is_null());
data->set_deopt_entry_code(kind, *code);
}
void Deoptimizer::EnsureCodeForDeoptimizationEntries(Isolate* isolate) {
EnsureCodeForDeoptimizationEntry(isolate, DeoptimizeKind::kEager);
EnsureCodeForDeoptimizationEntry(isolate, DeoptimizeKind::kLazy);
EnsureCodeForDeoptimizationEntry(isolate, DeoptimizeKind::kSoft);
EnsureCodeForDeoptimizationEntry(isolate, DeoptimizeKind::kBailout);
}
FrameDescription::FrameDescription(uint32_t frame_size, int parameter_count)
: frame_size_(frame_size),
parameter_count_(parameter_count),

View File

@ -500,12 +500,13 @@ class Deoptimizer : public Malloced {
static void ComputeOutputFrames(Deoptimizer* deoptimizer);
static Address GetDeoptimizationEntry(Isolate* isolate, DeoptimizeKind kind);
V8_EXPORT_PRIVATE static Builtins::Name GetDeoptimizationEntry(
Isolate* isolate, DeoptimizeKind kind);
// Returns true if {addr} is a deoptimization entry and stores its type in
// {type}. Returns false if {addr} is not a deoptimization entry.
// {type_out}. Returns false if {addr} is not a deoptimization entry.
static bool IsDeoptimizationEntry(Isolate* isolate, Address addr,
DeoptimizeKind* type);
DeoptimizeKind* type_out);
// Code generation support.
static int input_offset() { return offsetof(Deoptimizer, input_); }
@ -520,25 +521,26 @@ class Deoptimizer : public Malloced {
V8_EXPORT_PRIVATE static int GetDeoptimizedCodeCount(Isolate* isolate);
static const int kNotDeoptimizationEntry = -1;
static void EnsureCodeForDeoptimizationEntry(Isolate* isolate,
DeoptimizeKind kind);
static void EnsureCodeForDeoptimizationEntries(Isolate* isolate);
Isolate* isolate() const { return isolate_; }
static const int kMaxNumberOfEntries = 16384;
static constexpr int kMaxNumberOfEntries = 16384;
// This marker is passed to Deoptimizer::New as {bailout_id} on platforms
// that have fixed deopt sizes (see also kSupportsFixedDeoptExitSizes). The
// actual deoptimization id is then calculated from the return address.
static constexpr unsigned kFixedExitSizeMarker = kMaxUInt32;
// Set to true when the architecture supports deoptimization exit sequences
// of a fixed size, that can be sorted so that the deoptimization index is
// deduced from the address of the deoptimization exit.
static const bool kSupportsFixedDeoptExitSizes;
// TODO(jgruber): Remove this, and support for variable deopt exit sizes,
// once all architectures use fixed exit sizes.
V8_EXPORT_PRIVATE static const bool kSupportsFixedDeoptExitSizes;
// Size of deoptimization exit sequence. This is only meaningful when
// kSupportsFixedDeoptExitSizes is true.
static const int kNonLazyDeoptExitSize;
static const int kLazyDeoptExitSize;
V8_EXPORT_PRIVATE static const int kNonLazyDeoptExitSize;
V8_EXPORT_PRIVATE static const int kLazyDeoptExitSize;
// Tracing.
static void TraceMarkForDeoptimization(Code code, const char* reason);
@ -555,9 +557,6 @@ class Deoptimizer : public Malloced {
Code FindOptimizedCode();
void DeleteFrameDescriptions();
static bool IsDeoptimizationEntry(Isolate* isolate, Address addr,
DeoptimizeKind type);
void DoComputeOutputFrames();
void DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
int frame_index, bool goto_catch_handler);
@ -579,10 +578,6 @@ class Deoptimizer : public Malloced {
static unsigned ComputeIncomingArgumentSize(SharedFunctionInfo shared);
static unsigned ComputeOutgoingArgumentSize(Code code, unsigned bailout_id);
static void GenerateDeoptimizationEntries(MacroAssembler* masm,
Isolate* isolate,
DeoptimizeKind kind);
static void MarkAllCodeForContext(NativeContext native_context);
static void DeoptimizeMarkedCodeForContext(NativeContext native_context);
// Searches the list of known deoptimizing code for a Code object
@ -827,36 +822,6 @@ class FrameDescription {
}
};
class DeoptimizerData {
public:
explicit DeoptimizerData(Heap* heap);
~DeoptimizerData();
#ifdef DEBUG
bool IsDeoptEntryCode(Code code) const {
for (int i = 0; i < kLastDeoptimizeKind + 1; i++) {
if (code == deopt_entry_code_[i]) return true;
}
return false;
}
#endif // DEBUG
private:
Heap* heap_;
static const int kLastDeoptimizeKind =
static_cast<int>(DeoptimizeKind::kLastDeoptimizeKind);
Code deopt_entry_code_[kLastDeoptimizeKind + 1];
Code deopt_entry_code(DeoptimizeKind kind);
void set_deopt_entry_code(DeoptimizeKind kind, Code code);
Deoptimizer* current_;
StrongRootsEntry* strong_roots_entry_;
friend class Deoptimizer;
DISALLOW_COPY_AND_ASSIGN(DeoptimizerData);
};
class TranslationBuffer {
public:
explicit TranslationBuffer(Zone* zone) : contents_(zone) {}

View File

@ -4,201 +4,14 @@
#if V8_TARGET_ARCH_IA32
#include "src/codegen/macro-assembler.h"
#include "src/codegen/register-configuration.h"
#include "src/codegen/safepoint-table.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/execution/frame-constants.h"
namespace v8 {
namespace internal {
const bool Deoptimizer::kSupportsFixedDeoptExitSizes = false;
const int Deoptimizer::kNonLazyDeoptExitSize = 0;
const int Deoptimizer::kLazyDeoptExitSize = 0;
#define __ masm->
void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
Isolate* isolate,
DeoptimizeKind deopt_kind) {
NoRootArrayScope no_root_array(masm);
// Save all general purpose registers before messing with them.
const int kNumberOfRegisters = Register::kNumRegisters;
const int kDoubleRegsSize = kDoubleSize * XMMRegister::kNumRegisters;
__ AllocateStackSpace(kDoubleRegsSize);
const RegisterConfiguration* config = RegisterConfiguration::Default();
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
XMMRegister xmm_reg = XMMRegister::from_code(code);
int offset = code * kDoubleSize;
__ movsd(Operand(esp, offset), xmm_reg);
}
__ pushad();
ExternalReference c_entry_fp_address =
ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate);
__ mov(masm->ExternalReferenceAsOperand(c_entry_fp_address, esi), ebp);
const int kSavedRegistersAreaSize =
kNumberOfRegisters * kSystemPointerSize + kDoubleRegsSize;
// The bailout id is passed in ebx by the caller.
// Get the address of the location in the code object
// and compute the fp-to-sp delta in register edx.
__ mov(ecx, Operand(esp, kSavedRegistersAreaSize));
__ lea(edx, Operand(esp, kSavedRegistersAreaSize + 1 * kSystemPointerSize));
__ sub(edx, ebp);
__ neg(edx);
// Allocate a new deoptimizer object.
__ PrepareCallCFunction(6, eax);
__ mov(eax, Immediate(0));
Label context_check;
__ mov(edi, Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset));
__ JumpIfSmi(edi, &context_check);
__ mov(eax, Operand(ebp, StandardFrameConstants::kFunctionOffset));
__ bind(&context_check);
__ mov(Operand(esp, 0 * kSystemPointerSize), eax); // Function.
__ mov(Operand(esp, 1 * kSystemPointerSize),
Immediate(static_cast<int>(deopt_kind)));
__ mov(Operand(esp, 2 * kSystemPointerSize), ebx); // Bailout id.
__ mov(Operand(esp, 3 * kSystemPointerSize), ecx); // Code address or 0.
__ mov(Operand(esp, 4 * kSystemPointerSize), edx); // Fp-to-sp delta.
__ mov(Operand(esp, 5 * kSystemPointerSize),
Immediate(ExternalReference::isolate_address(isolate)));
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::new_deoptimizer_function(), 6);
}
// Preserve deoptimizer object in register eax and get the input
// frame descriptor pointer.
__ mov(esi, Operand(eax, Deoptimizer::input_offset()));
// Fill in the input registers.
for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
int offset =
(i * kSystemPointerSize) + FrameDescription::registers_offset();
__ pop(Operand(esi, offset));
}
int double_regs_offset = FrameDescription::double_registers_offset();
// Fill in the double input registers.
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
int dst_offset = code * kDoubleSize + double_regs_offset;
int src_offset = code * kDoubleSize;
__ movsd(xmm0, Operand(esp, src_offset));
__ movsd(Operand(esi, dst_offset), xmm0);
}
// Clear FPU all exceptions.
// TODO(ulan): Find out why the TOP register is not zero here in some cases,
// and check that the generated code never deoptimizes with unbalanced stack.
__ fnclex();
// Mark the stack as not iterable for the CPU profiler which won't be able to
// walk the stack without the return address.
__ mov_b(__ ExternalReferenceAsOperand(
ExternalReference::stack_is_iterable_address(isolate), edx),
Immediate(0));
// Remove the return address and the double registers.
__ add(esp, Immediate(kDoubleRegsSize + 1 * kSystemPointerSize));
// Compute a pointer to the unwinding limit in register ecx; that is
// the first stack slot not part of the input frame.
__ mov(ecx, Operand(esi, FrameDescription::frame_size_offset()));
__ add(ecx, esp);
// Unwind the stack down to - but not including - the unwinding
// limit and copy the contents of the activation frame to the input
// frame description.
__ lea(edx, Operand(esi, FrameDescription::frame_content_offset()));
Label pop_loop_header;
__ jmp(&pop_loop_header);
Label pop_loop;
__ bind(&pop_loop);
__ pop(Operand(edx, 0));
__ add(edx, Immediate(sizeof(uint32_t)));
__ bind(&pop_loop_header);
__ cmp(ecx, esp);
__ j(not_equal, &pop_loop);
// Compute the output frame in the deoptimizer.
__ push(eax);
__ PrepareCallCFunction(1, esi);
__ mov(Operand(esp, 0 * kSystemPointerSize), eax);
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::compute_output_frames_function(), 1);
}
__ pop(eax);
__ mov(esp, Operand(eax, Deoptimizer::caller_frame_top_offset()));
// Replace the current (input) frame with the output frames.
Label outer_push_loop, inner_push_loop, outer_loop_header, inner_loop_header;
// Outer loop state: eax = current FrameDescription**, edx = one
// past the last FrameDescription**.
__ mov(edx, Operand(eax, Deoptimizer::output_count_offset()));
__ mov(eax, Operand(eax, Deoptimizer::output_offset()));
__ lea(edx, Operand(eax, edx, times_system_pointer_size, 0));
__ jmp(&outer_loop_header);
__ bind(&outer_push_loop);
// Inner loop state: esi = current FrameDescription*, ecx = loop
// index.
__ mov(esi, Operand(eax, 0));
__ mov(ecx, Operand(esi, FrameDescription::frame_size_offset()));
__ jmp(&inner_loop_header);
__ bind(&inner_push_loop);
__ sub(ecx, Immediate(sizeof(uint32_t)));
__ push(Operand(esi, ecx, times_1, FrameDescription::frame_content_offset()));
__ bind(&inner_loop_header);
__ test(ecx, ecx);
__ j(not_zero, &inner_push_loop);
__ add(eax, Immediate(kSystemPointerSize));
__ bind(&outer_loop_header);
__ cmp(eax, edx);
__ j(below, &outer_push_loop);
// In case of a failed STUB, we have to restore the XMM registers.
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
XMMRegister xmm_reg = XMMRegister::from_code(code);
int src_offset = code * kDoubleSize + double_regs_offset;
__ movsd(xmm_reg, Operand(esi, src_offset));
}
// Push pc and continuation from the last output frame.
__ push(Operand(esi, FrameDescription::pc_offset()));
__ push(Operand(esi, FrameDescription::continuation_offset()));
// Push the registers from the last output frame.
for (int i = 0; i < kNumberOfRegisters; i++) {
int offset =
(i * kSystemPointerSize) + FrameDescription::registers_offset();
__ push(Operand(esi, offset));
}
__ mov_b(__ ExternalReferenceAsOperand(
ExternalReference::stack_is_iterable_address(isolate), edx),
Immediate(1));
// Restore the registers from the stack.
__ popad();
__ InitializeRootRegister();
// Return to the continuation point.
__ ret(0);
}
const bool Deoptimizer::kSupportsFixedDeoptExitSizes = true;
const int Deoptimizer::kNonLazyDeoptExitSize = 5;
const int Deoptimizer::kLazyDeoptExitSize = 5;
Float32 RegisterValues::GetFloatRegister(unsigned n) const {
return Float32::FromBits(
@ -220,8 +33,6 @@ void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
void FrameDescription::SetPc(intptr_t pc) { pc_ = pc; }
#undef __
} // namespace internal
} // namespace v8

View File

@ -4,217 +4,14 @@
#if V8_TARGET_ARCH_X64
#include "src/codegen/macro-assembler.h"
#include "src/codegen/register-configuration.h"
#include "src/codegen/safepoint-table.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/objects/objects-inl.h"
namespace v8 {
namespace internal {
const bool Deoptimizer::kSupportsFixedDeoptExitSizes = false;
const int Deoptimizer::kNonLazyDeoptExitSize = 0;
const int Deoptimizer::kLazyDeoptExitSize = 0;
#define __ masm->
void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
Isolate* isolate,
DeoptimizeKind deopt_kind) {
NoRootArrayScope no_root_array(masm);
// Save all general purpose registers before messing with them.
const int kNumberOfRegisters = Register::kNumRegisters;
const int kDoubleRegsSize = kDoubleSize * XMMRegister::kNumRegisters;
__ AllocateStackSpace(kDoubleRegsSize);
const RegisterConfiguration* config = RegisterConfiguration::Default();
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
XMMRegister xmm_reg = XMMRegister::from_code(code);
int offset = code * kDoubleSize;
__ Movsd(Operand(rsp, offset), xmm_reg);
}
// We push all registers onto the stack, even though we do not need
// to restore all later.
for (int i = 0; i < kNumberOfRegisters; i++) {
Register r = Register::from_code(i);
__ pushq(r);
}
const int kSavedRegistersAreaSize =
kNumberOfRegisters * kSystemPointerSize + kDoubleRegsSize;
__ Store(
ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate),
rbp);
// We use this to keep the value of the fifth argument temporarily.
// Unfortunately we can't store it directly in r8 (used for passing
// this on linux), since it is another parameter passing register on windows.
Register arg5 = r11;
// The bailout id is passed using r13 on the stack.
__ movq(arg_reg_3, r13);
// Get the address of the location in the code object
// and compute the fp-to-sp delta in register arg5.
__ movq(arg_reg_4, Operand(rsp, kSavedRegistersAreaSize));
__ leaq(arg5, Operand(rsp, kSavedRegistersAreaSize + kPCOnStackSize));
__ subq(arg5, rbp);
__ negq(arg5);
// Allocate a new deoptimizer object.
__ PrepareCallCFunction(6);
__ movq(rax, Immediate(0));
Label context_check;
__ movq(rdi, Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset));
__ JumpIfSmi(rdi, &context_check);
__ movq(rax, Operand(rbp, StandardFrameConstants::kFunctionOffset));
__ bind(&context_check);
__ movq(arg_reg_1, rax);
__ Set(arg_reg_2, static_cast<int>(deopt_kind));
// Args 3 and 4 are already in the right registers.
// On windows put the arguments on the stack (PrepareCallCFunction
// has created space for this). On linux pass the arguments in r8 and r9.
#ifdef V8_TARGET_OS_WIN
__ movq(Operand(rsp, 4 * kSystemPointerSize), arg5);
__ LoadAddress(arg5, ExternalReference::isolate_address(isolate));
__ movq(Operand(rsp, 5 * kSystemPointerSize), arg5);
#else
__ movq(r8, arg5);
__ LoadAddress(r9, ExternalReference::isolate_address(isolate));
#endif
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::new_deoptimizer_function(), 6);
}
// Preserve deoptimizer object in register rax and get the input
// frame descriptor pointer.
__ movq(rbx, Operand(rax, Deoptimizer::input_offset()));
// Fill in the input registers.
for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
int offset =
(i * kSystemPointerSize) + FrameDescription::registers_offset();
__ PopQuad(Operand(rbx, offset));
}
// Fill in the double input registers.
int double_regs_offset = FrameDescription::double_registers_offset();
for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
int dst_offset = i * kDoubleSize + double_regs_offset;
__ popq(Operand(rbx, dst_offset));
}
// Mark the stack as not iterable for the CPU profiler which won't be able to
// walk the stack without the return address.
__ movb(__ ExternalReferenceAsOperand(
ExternalReference::stack_is_iterable_address(isolate)),
Immediate(0));
// Remove the return address from the stack.
__ addq(rsp, Immediate(kPCOnStackSize));
// Compute a pointer to the unwinding limit in register rcx; that is
// the first stack slot not part of the input frame.
__ movq(rcx, Operand(rbx, FrameDescription::frame_size_offset()));
__ addq(rcx, rsp);
// Unwind the stack down to - but not including - the unwinding
// limit and copy the contents of the activation frame to the input
// frame description.
__ leaq(rdx, Operand(rbx, FrameDescription::frame_content_offset()));
Label pop_loop_header;
__ jmp(&pop_loop_header);
Label pop_loop;
__ bind(&pop_loop);
__ Pop(Operand(rdx, 0));
__ addq(rdx, Immediate(sizeof(intptr_t)));
__ bind(&pop_loop_header);
__ cmpq(rcx, rsp);
__ j(not_equal, &pop_loop);
// Compute the output frame in the deoptimizer.
__ pushq(rax);
__ PrepareCallCFunction(2);
__ movq(arg_reg_1, rax);
__ LoadAddress(arg_reg_2, ExternalReference::isolate_address(isolate));
{
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(ExternalReference::compute_output_frames_function(), 2);
}
__ popq(rax);
__ movq(rsp, Operand(rax, Deoptimizer::caller_frame_top_offset()));
// Replace the current (input) frame with the output frames.
Label outer_push_loop, inner_push_loop, outer_loop_header, inner_loop_header;
// Outer loop state: rax = current FrameDescription**, rdx = one past the
// last FrameDescription**.
__ movl(rdx, Operand(rax, Deoptimizer::output_count_offset()));
__ movq(rax, Operand(rax, Deoptimizer::output_offset()));
__ leaq(rdx, Operand(rax, rdx, times_system_pointer_size, 0));
__ jmp(&outer_loop_header);
__ bind(&outer_push_loop);
// Inner loop state: rbx = current FrameDescription*, rcx = loop index.
__ movq(rbx, Operand(rax, 0));
__ movq(rcx, Operand(rbx, FrameDescription::frame_size_offset()));
__ jmp(&inner_loop_header);
__ bind(&inner_push_loop);
__ subq(rcx, Immediate(sizeof(intptr_t)));
__ Push(Operand(rbx, rcx, times_1, FrameDescription::frame_content_offset()));
__ bind(&inner_loop_header);
__ testq(rcx, rcx);
__ j(not_zero, &inner_push_loop);
__ addq(rax, Immediate(kSystemPointerSize));
__ bind(&outer_loop_header);
__ cmpq(rax, rdx);
__ j(below, &outer_push_loop);
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
XMMRegister xmm_reg = XMMRegister::from_code(code);
int src_offset = code * kDoubleSize + double_regs_offset;
__ Movsd(xmm_reg, Operand(rbx, src_offset));
}
// Push pc and continuation from the last output frame.
__ PushQuad(Operand(rbx, FrameDescription::pc_offset()));
__ PushQuad(Operand(rbx, FrameDescription::continuation_offset()));
// Push the registers from the last output frame.
for (int i = 0; i < kNumberOfRegisters; i++) {
int offset =
(i * kSystemPointerSize) + FrameDescription::registers_offset();
__ PushQuad(Operand(rbx, offset));
}
// Restore the registers from the stack.
for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
Register r = Register::from_code(i);
// Do not restore rsp, simply pop the value into the next register
// and overwrite this afterwards.
if (r == rsp) {
DCHECK_GT(i, 0);
r = Register::from_code(i - 1);
}
__ popq(r);
}
__ movb(__ ExternalReferenceAsOperand(
ExternalReference::stack_is_iterable_address(isolate)),
Immediate(1));
// Return to the continuation point.
__ ret(0);
}
const bool Deoptimizer::kSupportsFixedDeoptExitSizes = true;
const int Deoptimizer::kNonLazyDeoptExitSize = 7;
const int Deoptimizer::kLazyDeoptExitSize = 7;
Float32 RegisterValues::GetFloatRegister(unsigned n) const {
return Float32::FromBits(
@ -236,8 +33,6 @@ void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
void FrameDescription::SetPc(intptr_t pc) { pc_ = pc; }
#undef __
} // namespace internal
} // namespace v8

View File

@ -253,8 +253,7 @@ static void PrintRelocInfo(StringBuilder* out, Isolate* isolate,
host.as_wasm_code()->native_module()->GetRuntimeStubId(
relocinfo->wasm_stub_call_address()));
out->AddFormatted(" ;; wasm stub: %s", runtime_stub_name);
} else if (RelocInfo::IsRuntimeEntry(rmode) && isolate &&
isolate->deoptimizer_data() != nullptr) {
} else if (RelocInfo::IsRuntimeEntry(rmode) && isolate != nullptr) {
// A runtime entry relocinfo might be a deoptimization bailout.
Address addr = relocinfo->target_address();
DeoptimizeKind type;

View File

@ -1296,9 +1296,8 @@ void JSFunction::JSFunctionPrint(std::ostream& os) { // NOLINT
os << "\n - kind: " << shared().kind();
os << "\n - context: " << Brief(context());
os << "\n - code: " << Brief(code());
if (code().kind() == CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING) {
os << "\n - FunctionTester function";
if (code().kind() == CodeKind::FOR_TESTING) {
os << "\n - FOR_TESTING";
} else if (ActiveTierIsIgnition()) {
os << "\n - interpreted";
if (shared().HasBytecodeArray()) {

View File

@ -57,6 +57,10 @@ class IsolateData final {
static constexpr int builtin_entry_table_offset() {
return kBuiltinEntryTableOffset - kIsolateRootBias;
}
static constexpr int builtin_entry_slot_offset(Builtins::Name builtin_index) {
CONSTEXPR_DCHECK(Builtins::IsBuiltinId(builtin_index));
return builtin_entry_table_offset() + builtin_index * kSystemPointerSize;
}
// Root-register-relative offset of the builtins table.
static constexpr int builtins_table_offset() {

View File

@ -3076,8 +3076,6 @@ void Isolate::Deinit() {
ReleaseSharedPtrs();
delete deoptimizer_data_;
deoptimizer_data_ = nullptr;
string_table_.reset();
builtins_.TearDown();
bootstrapper_->TearDown();
@ -3537,8 +3535,6 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
}
DCHECK_NOT_NULL(wasm_engine_);
deoptimizer_data_ = new DeoptimizerData(heap());
if (setup_delegate_ == nullptr) {
setup_delegate_ = new SetupIsolateDelegate(create_heap_objects);
}

View File

@ -77,7 +77,7 @@ class CompilationStatistics;
class CompilerDispatcher;
class Counters;
class Debug;
class DeoptimizerData;
class Deoptimizer;
class DescriptorLookupCache;
class EmbeddedFileWriterInterface;
class EternalHandles;
@ -1025,7 +1025,17 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
StubCache* load_stub_cache() { return load_stub_cache_; }
StubCache* store_stub_cache() { return store_stub_cache_; }
DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
Deoptimizer* GetAndClearCurrentDeoptimizer() {
Deoptimizer* result = current_deoptimizer_;
CHECK_NOT_NULL(result);
current_deoptimizer_ = nullptr;
return result;
}
void set_current_deoptimizer(Deoptimizer* deoptimizer) {
DCHECK_NULL(current_deoptimizer_);
DCHECK_NOT_NULL(deoptimizer);
current_deoptimizer_ = deoptimizer;
}
bool deoptimizer_lazy_throw() const { return deoptimizer_lazy_throw_; }
void set_deoptimizer_lazy_throw(bool value) {
deoptimizer_lazy_throw_ = value;
@ -1731,7 +1741,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
Logger* logger_ = nullptr;
StubCache* load_stub_cache_ = nullptr;
StubCache* store_stub_cache_ = nullptr;
DeoptimizerData* deoptimizer_data_ = nullptr;
Deoptimizer* current_deoptimizer_ = nullptr;
bool deoptimizer_lazy_throw_ = false;
MaterializedObjectStore* materialized_object_store_ = nullptr;
bool capture_stack_trace_for_uncaught_exceptions_ = false;

View File

@ -150,10 +150,6 @@ MaybeHandle<Code> Factory::CodeBuilder::BuildInternal(
if (result.is_null()) return MaybeHandle<Code>();
}
if (!is_movable_) {
result = heap->EnsureImmovableCode(result, object_size);
}
// The code object has not been fully initialized yet. We rely on the
// fact that no allocation will happen from this point on.
DisallowHeapAllocation no_gc;

View File

@ -837,11 +837,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
return *this;
}
CodeBuilder& set_immovable() {
is_movable_ = false;
return *this;
}
CodeBuilder& set_is_turbofanned() {
is_turbofanned_ = true;
return *this;
@ -888,7 +883,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
BasicBlockProfilerData* profiler_data_ = nullptr;
bool is_executable_ = true;
bool read_only_data_container_ = false;
bool is_movable_ = true;
bool is_turbofanned_ = false;
int stack_slots_ = 0;
};

View File

@ -4984,33 +4984,6 @@ void Heap::DisableInlineAllocation() {
}
}
HeapObject Heap::EnsureImmovableCode(HeapObject heap_object, int object_size) {
// Code objects which should stay at a fixed address are allocated either
// in the first page of code space, in large object space, or (during
// snapshot creation) the containing page is marked as immovable.
DCHECK(!heap_object.is_null());
#ifndef V8_ENABLE_THIRD_PARTY_HEAP
DCHECK(code_space_->Contains(heap_object));
#endif
DCHECK_GE(object_size, 0);
if (!Heap::IsImmovable(heap_object)) {
if (isolate()->serializer_enabled() ||
code_space_->first_page()->Contains(heap_object.address())) {
BasicMemoryChunk::FromHeapObject(heap_object)->MarkNeverEvacuate();
} else {
// Discard the first code allocation, which was on a page where it could
// be moved.
CreateFillerObjectAt(heap_object.address(), object_size,
ClearRecordedSlots::kNo);
heap_object = AllocateRawCodeInLargeObjectSpace(object_size);
UnprotectAndRegisterMemoryChunk(heap_object);
ZapCodeObject(heap_object.address(), object_size);
OnAllocationEvent(heap_object, object_size);
}
}
return heap_object;
}
HeapObject Heap::AllocateRawWithLightRetrySlowPath(
int size, AllocationType allocation, AllocationOrigin origin,
AllocationAlignment alignment) {
@ -5063,40 +5036,6 @@ HeapObject Heap::AllocateRawWithRetryOrFailSlowPath(
return HeapObject();
}
// TODO(jkummerow): Refactor this. AllocateRaw should take an "immovability"
// parameter and just do what's necessary.
HeapObject Heap::AllocateRawCodeInLargeObjectSpace(int size) {
AllocationResult alloc = code_lo_space()->AllocateRaw(size);
HeapObject result;
if (alloc.To(&result)) {
DCHECK(result != ReadOnlyRoots(this).exception());
return result;
}
// Two GCs before panicking.
for (int i = 0; i < 2; i++) {
CollectGarbage(alloc.RetrySpace(),
GarbageCollectionReason::kAllocationFailure);
alloc = code_lo_space()->AllocateRaw(size);
if (alloc.To(&result)) {
DCHECK(result != ReadOnlyRoots(this).exception());
return result;
}
}
isolate()->counters()->gc_last_resort_from_handles()->Increment();
CollectAllAvailableGarbage(GarbageCollectionReason::kLastResort);
{
AlwaysAllocateScope scope(this);
alloc = code_lo_space()->AllocateRaw(size);
}
if (alloc.To(&result)) {
DCHECK(result != ReadOnlyRoots(this).exception());
return result;
}
// TODO(1181417): Fix this.
FatalProcessOutOfMemory("CALL_AND_RETRY_LAST");
return HeapObject();
}
void Heap::SetUp() {
#ifdef V8_ENABLE_ALLOCATION_TIMEOUT
allocation_timeout_ = NextAllocationTimeout();

View File

@ -1977,17 +1977,10 @@ class Heap {
int size, AllocationType allocation, AllocationOrigin origin,
AllocationAlignment alignment = kWordAligned);
V8_WARN_UNUSED_RESULT HeapObject AllocateRawCodeInLargeObjectSpace(int size);
// Allocates a heap object based on the map.
V8_WARN_UNUSED_RESULT AllocationResult Allocate(Map map,
AllocationType allocation);
// Takes a code object and checks if it is on memory which is not subject to
// compaction. This method will return a new code object on an immovable
// memory location if the original code object was movable.
HeapObject EnsureImmovableCode(HeapObject heap_object, int object_size);
// Allocates a partial map for bootstrapping.
V8_WARN_UNUSED_RESULT AllocationResult
AllocatePartialMap(InstanceType instance_type, int instance_size);

View File

@ -2175,7 +2175,7 @@ void ExistingCodeLogger::LogCodeObject(Object object) {
return; // We log this later using LogCompiledFunctions.
case CodeKind::BYTECODE_HANDLER:
return; // We log it later by walking the dispatch table.
case CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING:
case CodeKind::FOR_TESTING:
description = "STUB code";
tag = CodeEventListener::STUB_TAG;
break;

View File

@ -11,22 +11,20 @@
namespace v8 {
namespace internal {
// TODO(jgruber): Convert deopt entries to builtins and rename
// DEOPT_ENTRIES_OR_FOR_TESTING to FOR_TESTING.
#define CODE_KIND_LIST(V) \
V(TURBOFAN) \
V(BYTECODE_HANDLER) \
V(DEOPT_ENTRIES_OR_FOR_TESTING) \
V(BUILTIN) \
V(REGEXP) \
V(WASM_FUNCTION) \
V(WASM_TO_CAPI_FUNCTION) \
V(WASM_TO_JS_FUNCTION) \
V(JS_TO_WASM_FUNCTION) \
V(JS_TO_JS_FUNCTION) \
V(C_WASM_ENTRY) \
V(INTERPRETED_FUNCTION) \
V(NATIVE_CONTEXT_INDEPENDENT) \
#define CODE_KIND_LIST(V) \
V(TURBOFAN) \
V(BYTECODE_HANDLER) \
V(FOR_TESTING) \
V(BUILTIN) \
V(REGEXP) \
V(WASM_FUNCTION) \
V(WASM_TO_CAPI_FUNCTION) \
V(WASM_TO_JS_FUNCTION) \
V(JS_TO_WASM_FUNCTION) \
V(JS_TO_JS_FUNCTION) \
V(C_WASM_ENTRY) \
V(INTERPRETED_FUNCTION) \
V(NATIVE_CONTEXT_INDEPENDENT) \
V(TURBOPROP)
enum class CodeKind {

View File

@ -89,13 +89,6 @@ bool IsUnexpectedCodeObject(Isolate* isolate, HeapObject obj) {
if (!obj.IsCode()) return false;
Code code = Code::cast(obj);
// TODO(v8:8768): Deopt entry code should not be serialized.
if (code.kind() == CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING &&
isolate->deoptimizer_data() != nullptr) {
if (isolate->deoptimizer_data()->IsDeoptEntryCode(code)) return false;
}
if (code.kind() == CodeKind::REGEXP) return false;
if (!code.is_builtin()) return true;
if (code.is_off_heap_trampoline()) return false;

View File

@ -21,9 +21,8 @@ Handle<Code> AssembleCodeImpl(std::function<void(MacroAssembler&)> assemble) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
if (FLAG_print_code) {
code->Print();
}

View File

@ -23,8 +23,7 @@ class CodeAssemblerTester {
const char* name = "test")
: zone_(isolate->allocator(), ZONE_NAME, kCompressGraphZone),
scope_(isolate),
state_(isolate, &zone_, descriptor,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING, name,
state_(isolate, &zone_, descriptor, CodeKind::FOR_TESTING, name,
PoisoningMitigationLevel::kDontPoison, Builtins::kNoBuiltinId) {}
// Test generating code for a stub. Assumes VoidDescriptor call interface.
@ -48,8 +47,7 @@ class CodeAssemblerTester {
const char* name = "test")
: zone_(isolate->allocator(), ZONE_NAME, kCompressGraphZone),
scope_(isolate),
state_(isolate, &zone_, call_descriptor,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING, name,
state_(isolate, &zone_, call_descriptor, CodeKind::FOR_TESTING, name,
PoisoningMitigationLevel::kDontPoison, Builtins::kNoBuiltinId) {}
CodeAssemblerState* state() { return &state_; }

View File

@ -91,7 +91,7 @@ class RawMachineAssemblerTester : public HandleAndZoneScope,
}
private:
CodeKind kind_ = CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING;
CodeKind kind_ = CodeKind::FOR_TESTING;
MaybeHandle<Code> code_;
};

View File

@ -965,10 +965,10 @@ class CodeGeneratorTester {
int extra_stack_space = 0)
: zone_(environment->main_zone()),
info_(ArrayVector("test"), environment->main_zone(),
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING),
CodeKind::FOR_TESTING),
linkage_(environment->test_descriptor()),
frame_(environment->test_descriptor()->CalculateFixedFrameSize(
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)) {
CodeKind::FOR_TESTING)) {
// Pick half of the stack parameters at random and move them into spill
// slots, separated by `extra_stack_space` bytes.
// When testing a move with stack slots using CheckAssembleMove or

View File

@ -109,7 +109,7 @@ TEST(TestLinkageStubCall) {
Zone zone(isolate->allocator(), ZONE_NAME);
Callable callable = Builtins::CallableFor(isolate, Builtins::kToNumber);
OptimizedCompilationInfo info(ArrayVector("test"), &zone,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING);
CodeKind::FOR_TESTING);
auto call_descriptor = Linkage::GetStubCallDescriptor(
&zone, callable.descriptor(), 0, CallDescriptor::kNoFlags,
Operator::kNoProperties);
@ -130,7 +130,7 @@ TEST(TestFPLinkageStubCall) {
Callable callable =
Builtins::CallableFor(isolate, Builtins::kWasmFloat64ToNumber);
OptimizedCompilationInfo info(ArrayVector("test"), &zone,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING);
CodeKind::FOR_TESTING);
auto call_descriptor = Linkage::GetStubCallDescriptor(
&zone, callable.descriptor(), 0, CallDescriptor::kNoFlags,
Operator::kNoProperties);

View File

@ -246,7 +246,7 @@ Handle<Code> CompileGraph(const char* name, CallDescriptor* call_descriptor,
Graph* graph, Schedule* schedule = nullptr) {
Isolate* isolate = CcTest::InitIsolateOnce();
OptimizedCompilationInfo info(ArrayVector("testing"), graph->zone(),
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING);
CodeKind::FOR_TESTING);
Handle<Code> code = Pipeline::GenerateCodeForTesting(
&info, isolate, call_descriptor, graph,
AssemblerOptions::Default(isolate), schedule)

View File

@ -48,7 +48,6 @@
V(StressHandles) \
V(TestMemoryReducerSampleJsCalls) \
V(TestSizeOfObjects) \
V(Regress5831) \
V(Regress10560) \
V(Regress538257) \
V(Regress587004) \

View File

@ -395,9 +395,7 @@ UNINITIALIZED_TEST(ConcurrentRecordRelocSlot) {
CodeDesc desc;
masm.GetCode(i_isolate, &desc);
Handle<Code> code_handle =
Factory::CodeBuilder(i_isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(i_isolate, desc, CodeKind::FOR_TESTING).Build();
heap::AbandonCurrentlyFreeMemory(heap->old_space());
Handle<HeapNumber> value_handle(
i_isolate->factory()->NewHeapNumber<AllocationType::kOld>(1.1));

View File

@ -206,9 +206,8 @@ HEAP_TEST(TestNewSpaceRefsInCopiedCode) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
Handle<Code> copy;
{
@ -231,9 +230,8 @@ static void CheckFindCodeObject(Isolate* isolate) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
CHECK(code->IsCode());
HeapObject obj = HeapObject::cast(*code);
@ -244,9 +242,8 @@ static void CheckFindCodeObject(Isolate* isolate) {
CHECK_EQ(*code, found);
}
Handle<Code> copy = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> copy =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
HeapObject obj_copy = HeapObject::cast(*copy);
Object not_right =
isolate->FindCodeObject(obj_copy.address() + obj_copy.Size() / 2);
@ -6520,68 +6517,6 @@ HEAP_TEST(Regress670675) {
DCHECK(marking->IsStopped());
}
namespace {
Handle<Code> GenerateDummyImmovableCode(Isolate* isolate) {
Assembler assm(AssemblerOptions{});
const int kNumberOfNops = 1 << 10;
for (int i = 0; i < kNumberOfNops; i++) {
assm.nop(); // supported on all architectures
}
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.set_immovable()
.Build();
CHECK(code->IsCode());
return code;
}
} // namespace
HEAP_TEST(Regress5831) {
CcTest::InitializeVM();
Heap* heap = CcTest::heap();
Isolate* isolate = CcTest::i_isolate();
HandleScope handle_scope(isolate);
// Used to ensure that the generated code is not collected.
const int kInitialSize = 32;
Handle<FixedArray> array = isolate->factory()->NewFixedArray(kInitialSize);
// Ensure that all immovable code space pages are full and we overflow into
// LO_SPACE.
const int kMaxIterations = 1 << 16;
bool overflowed_into_lospace = false;
for (int i = 0; i < kMaxIterations; i++) {
Handle<Code> code = GenerateDummyImmovableCode(isolate);
array = FixedArray::SetAndGrow(isolate, array, i, code);
CHECK(heap->code_space()->Contains(*code) ||
heap->code_lo_space()->Contains(*code));
if (heap->code_lo_space()->Contains(*code)) {
overflowed_into_lospace = true;
break;
}
}
CHECK(overflowed_into_lospace);
// Fake a serializer run.
isolate->serializer_enabled_ = true;
// Generate the code.
Handle<Code> code = GenerateDummyImmovableCode(isolate);
CHECK_GE(MemoryChunkLayout::MaxRegularCodeObjectSize(), code->Size());
CHECK(!heap->code_space()->first_page()->Contains(code->address()));
// Ensure it's not in large object space.
MemoryChunk* chunk = MemoryChunk::FromHeapObject(*code);
CHECK(chunk->owner_identity() != LO_SPACE);
CHECK(chunk->NeverEvacuate());
}
HEAP_TEST(RegressMissingWriteBarrierInAllocate) {
if (!FLAG_incremental_marking) return;
ManualGCScope manual_gc_scope;
@ -7323,9 +7258,8 @@ TEST(Regress10900) {
masm.Push(ReadOnlyRoots(heap).undefined_value_handle());
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
{
// Generate multiple code pages.
CodeSpaceMemoryModificationScope modification_scope(isolate->heap());

View File

@ -51,9 +51,7 @@ TEST(WeakReferencesBasic) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
CHECK(code->IsCode());
lh->set_data1(HeapObjectReference::Weak(*code));

View File

@ -203,8 +203,7 @@ TEST(TryProbeStubCache) {
// Generate some number of handlers.
for (int i = 0; i < 30; i++) {
handlers.push_back(
CreateCodeOfKind(CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING));
handlers.push_back(CreateCodeOfKind(CodeKind::FOR_TESTING));
}
// Ensure that GC does happen because from now on we are going to fill our

View File

@ -60,9 +60,8 @@ TEST(0) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -97,9 +96,8 @@ TEST(1) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -143,9 +141,8 @@ TEST(2) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -190,9 +187,8 @@ TEST(3) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -322,9 +318,7 @@ TEST(4) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -386,9 +380,7 @@ TEST(5) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -418,9 +410,8 @@ TEST(6) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -486,9 +477,8 @@ static void TestRoundingMode(VCVTTypes types,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -669,9 +659,8 @@ TEST(8) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -779,9 +768,8 @@ TEST(9) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -885,9 +873,8 @@ TEST(10) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -980,9 +967,8 @@ TEST(11) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -1107,9 +1093,7 @@ TEST(13) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -1180,9 +1164,8 @@ TEST(14) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -2062,9 +2045,7 @@ TEST(15) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -2339,9 +2320,8 @@ TEST(16) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -2419,9 +2399,7 @@ TEST(sdiv) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -2481,9 +2459,7 @@ TEST(udiv) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -2511,9 +2487,8 @@ TEST(smmla) {
__ bx(lr);
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2537,9 +2512,8 @@ TEST(smmul) {
__ bx(lr);
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2563,9 +2537,8 @@ TEST(sxtb) {
__ bx(lr);
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2589,9 +2562,8 @@ TEST(sxtab) {
__ bx(lr);
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2615,9 +2587,8 @@ TEST(sxth) {
__ bx(lr);
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2641,9 +2612,8 @@ TEST(sxtah) {
__ bx(lr);
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2667,9 +2637,8 @@ TEST(uxtb) {
__ bx(lr);
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2693,9 +2662,8 @@ TEST(uxtab) {
__ bx(lr);
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2719,9 +2687,8 @@ TEST(uxth) {
__ bx(lr);
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2745,9 +2712,8 @@ TEST(uxtah) {
__ bx(lr);
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2788,9 +2754,7 @@ TEST(rbit) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
@ -2870,8 +2834,7 @@ TEST(code_relative_offset) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
Handle<Code> code = Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING)
.set_self_reference(code_object)
.Build();
auto f = GeneratedCode<F_iiiii>::FromCode(*code);
@ -2911,9 +2874,8 @@ TEST(msr_mrs) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -3010,9 +2972,7 @@ TEST(ARMv8_float32_vrintX) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -3113,9 +3073,7 @@ TEST(ARMv8_vrintX) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -3252,9 +3210,7 @@ TEST(ARMv8_vsel) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -3345,9 +3301,7 @@ TEST(ARMv8_vminmax_f64) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -3427,9 +3381,7 @@ TEST(ARMv8_vminmax_f32) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -3562,9 +3514,7 @@ static GeneratedCode<F_ppiii> GenerateMacroFloatMinMax(
CodeDesc desc;
assm.GetCode(assm.isolate(), &desc);
Handle<Code> code =
Factory::CodeBuilder(assm.isolate(), desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(assm.isolate(), desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -3726,9 +3676,8 @@ TEST(unaligned_loads) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -3770,9 +3719,8 @@ TEST(unaligned_stores) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -3871,9 +3819,8 @@ TEST(vswp) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -4085,9 +4032,7 @@ TEST(split_add_immediate) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -4107,9 +4052,7 @@ TEST(split_add_immediate) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -4132,9 +4075,7 @@ TEST(split_add_immediate) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);

View File

@ -158,18 +158,16 @@ static void InitializeVM() {
#define RUN() simulator.RunFrom(reinterpret_cast<Instruction*>(code->entry()))
#define END() \
__ Debug("End test.", __LINE__, TRACE_DISABLE | LOG_ALL); \
core.Dump(&masm); \
__ PopCalleeSavedRegisters(); \
__ Ret(); \
{ \
CodeDesc desc; \
__ GetCode(masm.isolate(), &desc); \
code = Factory::CodeBuilder(isolate, desc, \
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING) \
.Build(); \
if (FLAG_print_code) code->Print(); \
#define END() \
__ Debug("End test.", __LINE__, TRACE_DISABLE | LOG_ALL); \
core.Dump(&masm); \
__ PopCalleeSavedRegisters(); \
__ Ret(); \
{ \
CodeDesc desc; \
__ GetCode(masm.isolate(), &desc); \
code = Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build(); \
if (FLAG_print_code) code->Print(); \
}
#else // ifdef USE_SIMULATOR.
@ -206,17 +204,15 @@ static void InitializeVM() {
f.Call(); \
}
#define END() \
core.Dump(&masm); \
__ PopCalleeSavedRegisters(); \
__ Ret(); \
{ \
CodeDesc desc; \
__ GetCode(masm.isolate(), &desc); \
code = Factory::CodeBuilder(isolate, desc, \
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING) \
.Build(); \
if (FLAG_print_code) code->Print(); \
#define END() \
core.Dump(&masm); \
__ PopCalleeSavedRegisters(); \
__ Ret(); \
{ \
CodeDesc desc; \
__ GetCode(masm.isolate(), &desc); \
code = Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build(); \
if (FLAG_print_code) code->Print(); \
}
#endif // ifdef USE_SIMULATOR.
@ -14887,8 +14883,7 @@ TEST(pool_size) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
code = Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
code = Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING)
.set_self_reference(masm.CodeObject())
.Build();

View File

@ -27,14 +27,14 @@
#include <stdlib.h>
#include "src/init/v8.h"
#include "src/base/platform/platform.h"
#include "src/base/utils/random-number-generator.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/diagnostics/disassembler.h"
#include "src/heap/factory.h"
#include "src/init/v8.h"
#include "src/utils/ostreams.h"
#include "test/cctest/cctest.h"
@ -62,9 +62,8 @@ TEST(AssemblerIa320) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -101,9 +100,8 @@ TEST(AssemblerIa321) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -144,9 +142,8 @@ TEST(AssemblerIa322) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -174,9 +171,8 @@ TEST(AssemblerIa323) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -204,9 +200,8 @@ TEST(AssemblerIa324) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -233,9 +228,8 @@ TEST(AssemblerIa325) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
F0 f = FUNCTION_CAST<F0>(code->entry());
int res = f();
CHECK_EQ(42, res);
@ -267,9 +261,8 @@ TEST(AssemblerIa326) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -300,9 +293,8 @@ TEST(AssemblerIa328) {
__ ret(0);
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -384,9 +376,8 @@ TEST(AssemblerMultiByteNop) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
CHECK(code->IsCode());
F0 f = FUNCTION_CAST<F0>(code->entry());
@ -436,9 +427,8 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
F0 f = FUNCTION_CAST<F0>(code->entry());
int res = f();
@ -502,9 +492,8 @@ TEST(AssemblerIa32Extractps) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -542,9 +531,8 @@ TEST(AssemblerIa32SSE) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -576,9 +564,8 @@ TEST(AssemblerIa32SSE3) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -805,9 +792,8 @@ TEST(AssemblerX64FMA_sd) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1034,9 +1020,8 @@ TEST(AssemblerX64FMA_ss) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1143,9 +1128,8 @@ TEST(AssemblerIa32BMI1) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1192,9 +1176,8 @@ TEST(AssemblerIa32LZCNT) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1241,9 +1224,8 @@ TEST(AssemblerIa32POPCNT) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1388,9 +1370,8 @@ TEST(AssemblerIa32BMI2) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1433,9 +1414,8 @@ TEST(AssemblerIa32JumpTables1) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1482,9 +1462,8 @@ TEST(AssemblerIa32JumpTables2) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1526,9 +1505,8 @@ TEST(Regress621926) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
@ -1539,6 +1517,29 @@ TEST(Regress621926) {
CHECK_EQ(1, f());
}
TEST(DeoptExitSizeIsFixed) {
CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
v8::internal::byte buffer[256];
MacroAssembler masm(isolate, v8::internal::CodeObjectRequired::kYes,
ExternalAssemblerBuffer(buffer, sizeof(buffer)));
STATIC_ASSERT(static_cast<int>(kFirstDeoptimizeKind) == 0);
for (int i = 0; i < kDeoptimizeKindCount; i++) {
DeoptimizeKind kind = static_cast<DeoptimizeKind>(i);
Builtins::Name target = Deoptimizer::GetDeoptimizationEntry(isolate, kind);
Label before_exit;
masm.bind(&before_exit);
masm.CallForDeoptimization(target, 42, &before_exit, kind, nullptr);
CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit),
kind == DeoptimizeKind::kLazy
? Deoptimizer::kLazyDeoptExitSize
: Deoptimizer::kNonLazyDeoptExitSize);
}
}
#undef __
} // namespace internal

View File

@ -64,9 +64,8 @@ TEST(MIPS0) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
int res = reinterpret_cast<int>(f.Call(0xAB0, 0xC, 0, 0, 0));
CHECK_EQ(static_cast<int32_t>(0xABC), res);
@ -100,9 +99,8 @@ TEST(MIPS1) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F1>::FromCode(*code);
int res = reinterpret_cast<int>(f.Call(50, 0, 0, 0, 0));
CHECK_EQ(1275, res);
@ -238,9 +236,8 @@ TEST(MIPS2) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
int res = reinterpret_cast<int>(f.Call(0xAB0, 0xC, 0, 0, 0));
CHECK_EQ(static_cast<int32_t>(0x31415926), res);
@ -339,9 +336,8 @@ TEST(MIPS3) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
// Double test values.
t.a = 1.5e14;
@ -442,9 +438,8 @@ TEST(MIPS4) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.a = 1.5e22;
t.b = 2.75e11;
@ -504,9 +499,8 @@ TEST(MIPS5) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.a = 1.5e4;
t.b = 2.75e8;
@ -573,9 +567,8 @@ TEST(MIPS6) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.ui = 0x11223344;
t.si = 0x99AABBCC;
@ -666,9 +659,8 @@ TEST(MIPS7) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.a = 1.5e14;
t.b = 2.75e11;
@ -764,9 +756,7 @@ TEST(MIPS8) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.input = 0x12345678;
f.Call(&t, 0x0, 0, 0, 0);
@ -810,9 +800,8 @@ TEST(MIPS9) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
USE(code);
}
@ -862,9 +851,8 @@ TEST(MIPS10) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.a = 2.147483646e+09; // 0x7FFFFFFE -> 0xFF80000041DFFFFF as double.
t.b_word = 0x0FF00FF0; // 0x0FF00FF0 -> 0x as double.
@ -990,9 +978,8 @@ TEST(MIPS11) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.reg_init = 0xAABBCCDD;
t.mem_init = 0x11223344;
@ -1116,9 +1103,8 @@ TEST(MIPS12) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.x = 1;
t.y = 2;
@ -1170,9 +1156,8 @@ TEST(MIPS13) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.cvt_big_in = 0xFFFFFFFF;
@ -1291,9 +1276,8 @@ TEST(MIPS14) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.round_up_in = 123.51;
@ -1397,9 +1381,7 @@ TEST(seleqz_selnez) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
(f.Call(&test, 0, 0, 0, 0));
@ -1513,9 +1495,7 @@ TEST(min_max) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputsa[i];
@ -1625,9 +1605,7 @@ TEST(rint_d) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int j = 0; j < 4; j++) {
@ -1674,9 +1652,7 @@ TEST(sel) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
const int test_size = 3;
@ -1808,9 +1784,7 @@ TEST(rint_s) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int j = 0; j < 4; j++) {
@ -1853,9 +1827,8 @@ TEST(Cvt_d_uw) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.input = inputs[i];
@ -1936,9 +1909,7 @@ TEST(mina_maxa) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputsa[i];
@ -2018,9 +1989,7 @@ TEST(trunc_l) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputs_D[i];
@ -2100,9 +2069,7 @@ TEST(movz_movn) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputs_D[i];
@ -2203,9 +2170,7 @@ TEST(movt_movd) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
(f.Call(&test, 0, 0, 0, 0));
@ -2289,9 +2254,8 @@ TEST(cvt_w_d) {
Test test;
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int j = 0; j < 4; j++) {
test.fcsr = fcsr_inputs[j];
@ -2357,9 +2321,8 @@ TEST(trunc_w) {
Test test;
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputs_D[i];
@ -2427,9 +2390,8 @@ TEST(round_w) {
Test test;
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputs_D[i];
@ -2500,9 +2462,7 @@ TEST(round_l) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputs_D[i];
@ -2574,9 +2534,8 @@ TEST(sub) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputfs_S[i];
@ -2654,9 +2613,8 @@ TEST(sqrt_rsqrt_recip) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
@ -2735,9 +2693,8 @@ TEST(neg) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputs_S[i];
@ -2793,9 +2750,8 @@ TEST(mul) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputfs_S[i];
@ -2850,9 +2806,8 @@ TEST(mov) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputs_D[i];
@ -2918,9 +2873,8 @@ TEST(floor_w) {
Test test;
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputs_D[i];
@ -2991,9 +2945,7 @@ TEST(floor_l) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputs_D[i];
@ -3064,9 +3016,8 @@ TEST(ceil_w) {
Test test;
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputs_D[i];
@ -3137,9 +3088,7 @@ TEST(ceil_l) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputs_D[i];
@ -3206,9 +3155,8 @@ TEST(jump_tables1) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -3272,9 +3220,8 @@ TEST(jump_tables2) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -3345,9 +3292,8 @@ TEST(jump_tables3) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -3398,9 +3344,7 @@ TEST(BITSWAP) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.r1 = 0x781A15C3;
t.r2 = 0x8B71FCDE;
@ -3534,9 +3478,7 @@ TEST(class_fmt) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.dSignalingNan = std::numeric_limits<double>::signaling_NaN();
@ -3626,9 +3568,8 @@ TEST(ABS) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
test.a = -2.0;
test.b = -2.0;
@ -3720,9 +3661,8 @@ TEST(ADD_FMT) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
test.a = 2.0;
test.b = 3.0;
@ -3876,9 +3816,7 @@ TEST(C_COND_FMT) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
test.dOp1 = 2.0;
test.dOp2 = 3.0;
@ -4078,9 +4016,7 @@ TEST(CMP_COND_FMT) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
uint64_t dTrue = 0xFFFFFFFFFFFFFFFF;
uint64_t dFalse = 0x0000000000000000;
@ -4265,9 +4201,8 @@ TEST(CVT) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
test.cvt_d_s_in = -0.51;
@ -4478,9 +4413,8 @@ TEST(DIV_FMT) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
@ -4571,9 +4505,8 @@ uint32_t run_align(uint32_t rs_value, uint32_t rt_value, uint8_t bp) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
@ -4627,9 +4560,8 @@ uint32_t run_aluipc(int16_t offset) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
PC = (uint32_t)code->entry(); // Set the program counter.
@ -4681,9 +4613,8 @@ uint32_t run_auipc(int16_t offset) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
PC = (uint32_t)code->entry(); // Set the program counter.
@ -4757,9 +4688,8 @@ uint32_t run_lwpc(int offset) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
@ -4838,9 +4768,8 @@ uint32_t run_jic(int16_t offset) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
@ -4910,9 +4839,8 @@ uint64_t run_beqzc(int32_t value, int32_t offset) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
@ -5017,9 +4945,8 @@ void run_bz_bnz(TestCaseMsaBranch* input, Branch GenerateBranch,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -5188,9 +5115,8 @@ uint32_t run_jialc(int16_t offset) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
@ -5237,9 +5163,8 @@ static uint32_t run_addiupc(int32_t imm19) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
PC = (uint32_t)code->entry(); // Set the program counter.
@ -5320,9 +5245,8 @@ int32_t run_bc(int32_t offset) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
@ -5402,9 +5326,8 @@ int32_t run_balc(int32_t offset) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
@ -5427,9 +5350,8 @@ uint32_t run_aui(uint32_t rs, uint16_t offset) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
@ -5517,9 +5439,8 @@ uint32_t run_bal(int16_t offset) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
@ -5570,9 +5491,8 @@ TEST(Trampoline) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
int32_t res = reinterpret_cast<int32_t>(f.Call(42, 42, 0, 0, 0));
@ -5698,9 +5618,8 @@ void helper_madd_msub_maddf_msubf(F func) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
const size_t kTableLength = sizeof(test_cases) / sizeof(TestCaseMaddMsub<T>);
@ -5784,9 +5703,8 @@ uint32_t run_Subu(uint32_t imm, int32_t num_instr) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
uint32_t res = reinterpret_cast<uint32_t>(f.Call(0, 0, 0, 0, 0));
@ -5889,9 +5807,8 @@ TEST(MSA_fill_copy) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -5958,9 +5875,8 @@ TEST(MSA_fill_copy_2) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -6016,9 +5932,8 @@ TEST(MSA_fill_copy_3) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -6062,9 +5977,8 @@ void run_msa_insert(int32_t rs_value, int n, msa_reg_t* w) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -6164,9 +6078,7 @@ TEST(MSA_move_v) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -6211,9 +6123,7 @@ void run_msa_sldi(OperFunc GenerateOperation,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -6297,9 +6207,8 @@ void run_msa_ctc_cfc(uint32_t value) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -6408,9 +6317,8 @@ void run_msa_i8(SecondaryField opcode, uint64_t ws_lo, uint64_t ws_hi,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -6587,9 +6495,8 @@ uint32_t run_Ins(uint32_t imm, uint32_t source, uint16_t pos, uint16_t size) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
uint32_t res = reinterpret_cast<uint32_t>(f.Call(0, 0, 0, 0, 0));
@ -6638,9 +6545,8 @@ uint32_t run_Ext(uint32_t source, uint16_t pos, uint16_t size) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F2>::FromCode(*code);
uint32_t res = reinterpret_cast<uint32_t>(f.Call(0, 0, 0, 0, 0));
@ -6701,9 +6607,8 @@ void run_msa_i5(struct TestCaseMsaI5* input, bool i5_sign_ext,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -7122,9 +7027,8 @@ void run_msa_2r(const struct TestCaseMsa2R* input,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -8173,9 +8077,8 @@ void run_msa_vector(struct TestCaseMsaVector* input,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -8262,9 +8165,8 @@ void run_msa_bit(struct TestCaseMsaBit* input, InstFunc GenerateInstructionFunc,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -8736,9 +8638,8 @@ void run_msa_i10(int32_t input, InstFunc GenerateVectorInstructionFunc,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -8815,9 +8716,8 @@ void run_msa_mi10(InstFunc GenerateVectorInstructionFunc) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -8895,9 +8795,8 @@ void run_msa_3r(struct TestCaseMsa3R* input, InstFunc GenerateI5InstructionFunc,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -9902,9 +9801,8 @@ void run_msa_3rf(const struct TestCaseMsa3RF* input,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -60,9 +60,8 @@ TEST(0) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -97,9 +96,8 @@ TEST(1) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -146,9 +144,8 @@ TEST(2) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -216,9 +213,8 @@ TEST(3) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -331,7 +327,7 @@ TEST(4) {
assm.GetCode(isolate, &desc);
Object code = isolate->heap()->CreateCode(
desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING,
CodeKind::FOR_TESTING,
Handle<Code>())->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
@ -391,7 +387,7 @@ TEST(5) {
assm.GetCode(isolate, &desc);
Object code = isolate->heap()->CreateCode(
desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING,
CodeKind::FOR_TESTING,
Handle<Code>())->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
@ -426,7 +422,7 @@ TEST(6) {
assm.GetCode(isolate, &desc);
Object code = isolate->heap()->CreateCode(
desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING,
CodeKind::FOR_TESTING,
Handle<Code>())->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
@ -501,7 +497,7 @@ static void TestRoundingMode(VCVTTypes types,
assm.GetCode(isolate, &desc);
Object code = isolate->heap()->CreateCode(
desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING,
CodeKind::FOR_TESTING,
Handle<Code>())->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
@ -688,7 +684,7 @@ TEST(8) {
assm.GetCode(isolate, &desc);
Object code = isolate->heap()->CreateCode(
desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING,
CodeKind::FOR_TESTING,
Handle<Code>())->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
@ -803,7 +799,7 @@ TEST(9) {
assm.GetCode(isolate, &desc);
Object code = isolate->heap()->CreateCode(
desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING,
CodeKind::FOR_TESTING,
Handle<Code>())->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
@ -914,7 +910,7 @@ TEST(10) {
assm.GetCode(isolate, &desc);
Object code = isolate->heap()->CreateCode(
desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING,
CodeKind::FOR_TESTING,
Handle<Code>())->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
@ -1011,7 +1007,7 @@ TEST(11) {
assm.GetCode(isolate, &desc);
Object code = isolate->heap()->CreateCode(
desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING,
CodeKind::FOR_TESTING,
Handle<Code>())->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG

View File

@ -63,9 +63,8 @@ TEST(0) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -103,9 +102,8 @@ TEST(1) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -155,9 +153,8 @@ TEST(2) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -211,9 +208,8 @@ TEST(3) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -254,7 +250,7 @@ TEST(4) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING, Handle<Code>());
desc, CodeKind::FOR_TESTING, Handle<Code>());
#ifdef DEBUG
code->Print();
#endif
@ -282,7 +278,7 @@ TEST(5) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING, Handle<Code>());
desc, CodeKind::FOR_TESTING, Handle<Code>());
#ifdef DEBUG
code->Print();
#endif
@ -316,7 +312,7 @@ TEST(6) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING, Handle<Code>());
desc, CodeKind::FOR_TESTING, Handle<Code>());
#ifdef DEBUG
code->Print();
#endif
@ -348,7 +344,7 @@ TEST(7) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING, Handle<Code>());
desc, CodeKind::FOR_TESTING, Handle<Code>());
#ifdef DEBUG
code->Print();
#endif
@ -379,7 +375,7 @@ TEST(8) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING, Handle<Code>());
desc, CodeKind::FOR_TESTING, Handle<Code>());
#ifdef DEBUG
code->Print();
#endif
@ -406,7 +402,7 @@ TEST(9) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING, Handle<Code>());
desc, CodeKind::FOR_TESTING, Handle<Code>());
#ifdef DEBUG
code->Print();
#endif
@ -490,9 +486,8 @@ TEST(10) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -545,9 +540,8 @@ TEST(11) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -600,9 +594,8 @@ TEST(12) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -665,9 +658,8 @@ TEST(13) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -757,9 +749,8 @@ TEST(14) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -848,9 +839,8 @@ TEST(15) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -896,9 +886,8 @@ TEST(16) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -971,9 +960,8 @@ TEST(17) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif
@ -1064,9 +1052,8 @@ TEST(18) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
code->Print();
#endif

View File

@ -743,9 +743,8 @@ TEST(AssemblerMultiByteNop) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F0>::FromCode(*code);
int res = f.Call();
@ -801,9 +800,8 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F0>::FromCode(*code);
int res = f.Call();
@ -867,9 +865,8 @@ TEST(AssemblerX64Extractps) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -905,9 +902,8 @@ TEST(AssemblerX64SSE) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -937,9 +933,8 @@ TEST(AssemblerX64SSE3) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1163,9 +1158,8 @@ TEST(AssemblerX64FMA_sd) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1390,9 +1384,8 @@ TEST(AssemblerX64FMA_ss) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1467,9 +1460,8 @@ TEST(AssemblerX64SSE_ss) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1554,9 +1546,8 @@ TEST(AssemblerX64AVX_ss) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1795,9 +1786,8 @@ TEST(AssemblerX64AVX_sd) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1988,9 +1978,8 @@ TEST(AssemblerX64BMI1) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -2049,9 +2038,8 @@ TEST(AssemblerX64LZCNT) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -2110,9 +2098,8 @@ TEST(AssemblerX64POPCNT) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -2374,9 +2361,8 @@ TEST(AssemblerX64BMI2) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -2419,9 +2405,8 @@ TEST(AssemblerX64JumpTables1) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2468,9 +2453,8 @@ TEST(AssemblerX64JumpTables2) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -2526,9 +2510,8 @@ TEST(AssemblerX64vmovups) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);

View File

@ -39,10 +39,9 @@ TEST(CodeLayoutWithoutUnwindingInfo) {
code_desc.unwinding_info_size = 0;
code_desc.origin = nullptr;
Handle<Code> code =
Factory::CodeBuilder(CcTest::i_isolate(), code_desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code = Factory::CodeBuilder(CcTest::i_isolate(), code_desc,
CodeKind::FOR_TESTING)
.Build();
CHECK(!code->has_unwinding_info());
CHECK_EQ(code->raw_instruction_size(), buffer_size);
@ -87,10 +86,9 @@ TEST(CodeLayoutWithUnwindingInfo) {
code_desc.unwinding_info_size = unwinding_info_size;
code_desc.origin = nullptr;
Handle<Code> code =
Factory::CodeBuilder(CcTest::i_isolate(), code_desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code = Factory::CodeBuilder(CcTest::i_isolate(), code_desc,
CodeKind::FOR_TESTING)
.Build();
CHECK(code->has_unwinding_info());
CHECK_EQ(code->raw_instruction_size(), buffer_size + unwinding_info_size);

View File

@ -131,7 +131,7 @@ Handle<JSFunction> CreateCsaDescriptorArrayLookup(Isolate* isolate) {
compiler::CodeAssemblerTester asm_tester(
isolate, kNumParams + 1, // +1 to include receiver.
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING);
CodeKind::FOR_TESTING);
{
CodeStubAssembler m(asm_tester.state());
@ -176,7 +176,7 @@ Handle<JSFunction> CreateCsaTransitionArrayLookup(Isolate* isolate) {
const int kNumParams = 2;
compiler::CodeAssemblerTester asm_tester(
isolate, kNumParams + 1, // +1 to include receiver.
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING);
CodeKind::FOR_TESTING);
{
CodeStubAssembler m(asm_tester.state());

View File

@ -988,9 +988,8 @@ TEST(DisasmIa320) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
USE(code);
#ifdef OBJECT_PRINT
StdoutStream os;

View File

@ -993,9 +993,8 @@ TEST(DisasmX64) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
USE(code);
#ifdef OBJECT_PRINT
StdoutStream os;

View File

@ -4068,8 +4068,7 @@ TEST(WeakReference) {
i::CodeDesc desc;
assm.GetCode(i_isolate, &desc);
i::Handle<i::Code> code =
i::Factory::CodeBuilder(i_isolate, desc,
i::CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
i::Factory::CodeBuilder(i_isolate, desc, i::CodeKind::FOR_TESTING)
.Build();
CHECK(code->IsCode());

View File

@ -29,6 +29,7 @@
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/execution/simulator.h"
#include "src/init/v8.h"
#include "src/objects/objects-inl.h"
@ -146,9 +147,8 @@ TEST(ExtractLane) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -278,9 +278,8 @@ TEST(ReplaceLane) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -311,6 +310,29 @@ TEST(ReplaceLane) {
}
}
TEST(DeoptExitSizeIsFixed) {
CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate, v8::internal::CodeObjectRequired::kYes,
buffer->CreateView());
STATIC_ASSERT(static_cast<int>(kFirstDeoptimizeKind) == 0);
for (int i = 0; i < kDeoptimizeKindCount; i++) {
DeoptimizeKind kind = static_cast<DeoptimizeKind>(i);
Builtins::Name target = Deoptimizer::GetDeoptimizationEntry(isolate, kind);
Label before_exit;
masm.bind(&before_exit);
masm.CallForDeoptimization(target, 42, &before_exit, kind, &before_exit);
CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit),
kind == DeoptimizeKind::kLazy
? Deoptimizer::kLazyDeoptExitSize
: Deoptimizer::kNonLazyDeoptExitSize);
}
}
#undef __
} // namespace test_macro_assembler_arm

View File

@ -27,13 +27,13 @@
#include <stdlib.h>
#include "src/init/v8.h"
#include "src/base/platform/platform.h"
#include "src/codegen/arm64/assembler-arm64-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/execution/simulator.h"
#include "src/heap/factory.h"
#include "src/init/v8.h"
#include "src/objects/objects-inl.h"
#include "src/objects/smi.h"
#include "src/utils/ostreams.h"
@ -65,9 +65,8 @@ TEST(EmbeddedObj) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef DEBUG
StdoutStream os;
code->Print(os);
@ -92,6 +91,29 @@ TEST(EmbeddedObj) {
#endif // V8_COMPRESS_POINTERS
}
TEST(DeoptExitSizeIsFixed) {
CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate, v8::internal::CodeObjectRequired::kYes,
buffer->CreateView());
STATIC_ASSERT(static_cast<int>(kFirstDeoptimizeKind) == 0);
for (int i = 0; i < kDeoptimizeKindCount; i++) {
DeoptimizeKind kind = static_cast<DeoptimizeKind>(i);
Builtins::Name target = Deoptimizer::GetDeoptimizationEntry(isolate, kind);
Label before_exit;
masm.bind(&before_exit);
masm.CallForDeoptimization(target, 42, &before_exit, kind, &before_exit);
CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit),
kind == DeoptimizeKind::kLazy
? Deoptimizer::kLazyDeoptExitSize
: Deoptimizer::kNonLazyDeoptExitSize);
}
}
#undef __
} // namespace test_macro_assembler_arm64

View File

@ -88,9 +88,8 @@ TEST(BYTESWAP) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (size_t i = 0; i < arraysize(test_values); i++) {
@ -199,9 +198,8 @@ TEST(jump_tables4) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -263,9 +261,8 @@ TEST(jump_tables5) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -352,9 +349,8 @@ TEST(jump_tables6) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -378,9 +374,8 @@ static uint32_t run_lsa(uint32_t rt, uint32_t rs, int8_t sa) {
CodeDesc desc;
assembler.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F1>::FromCode(*code);
@ -507,9 +502,8 @@ RET_TYPE run_Cvt(IN_TYPE x, Func GenerateConvertInstructionFunc) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F_CVT>::FromCode(*code);
@ -621,9 +615,7 @@ TEST(OverflowInstructions) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.lhs = ii;
t.rhs = jj;
@ -745,9 +737,8 @@ TEST(min_max_nan) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputsa[i];
@ -781,9 +772,8 @@ bool run_Unaligned(char* memory_buffer, int32_t in_offset, int32_t out_offset,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F_CVT>::FromCode(*code);
@ -1029,9 +1019,8 @@ bool run_Sltu(uint32_t rs, uint32_t rd, Func GenerateSltuInstructionFunc) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F_CVT>::FromCode(*code);
int32_t res = reinterpret_cast<int32_t>(f.Call(rs, rd, 0, 0, 0));
@ -1125,8 +1114,7 @@ static GeneratedCode<F4> GenerateMacroFloat32MinMax(MacroAssembler* masm) {
CodeDesc desc;
masm->GetCode(masm->isolate(), &desc);
Handle<Code> code =
Factory::CodeBuilder(masm->isolate(), desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
Factory::CodeBuilder(masm->isolate(), desc, CodeKind::FOR_TESTING)
.Build();
#ifdef DEBUG
StdoutStream os;
@ -1268,8 +1256,7 @@ static GeneratedCode<F4> GenerateMacroFloat64MinMax(MacroAssembler* masm) {
CodeDesc desc;
masm->GetCode(masm->isolate(), &desc);
Handle<Code> code =
Factory::CodeBuilder(masm->isolate(), desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
Factory::CodeBuilder(masm->isolate(), desc, CodeKind::FOR_TESTING)
.Build();
#ifdef DEBUG
StdoutStream os;

View File

@ -108,9 +108,8 @@ TEST(BYTESWAP) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (size_t i = 0; i < arraysize(test_values); i++) {
@ -164,9 +163,8 @@ TEST(LoadConstants) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<FV>::FromCode(*code);
(void)f.Call(reinterpret_cast<int64_t>(result), 0, 0, 0, 0);
@ -208,9 +206,8 @@ TEST(LoadAddress) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<FV>::FromCode(*code);
(void)f.Call(0, 0, 0, 0, 0);
@ -266,9 +263,8 @@ TEST(jump_tables4) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -337,9 +333,8 @@ TEST(jump_tables5) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -427,9 +422,8 @@ TEST(jump_tables6) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
@ -453,9 +447,8 @@ static uint64_t run_lsa(uint32_t rt, uint32_t rs, int8_t sa) {
CodeDesc desc;
assembler.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F1>::FromCode(*code);
@ -534,9 +527,8 @@ static uint64_t run_dlsa(uint64_t rt, uint64_t rs, int8_t sa) {
CodeDesc desc;
assembler.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<FV>::FromCode(*code);
@ -685,9 +677,8 @@ RET_TYPE run_Cvt(IN_TYPE x, Func GenerateConvertInstructionFunc) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F_CVT>::FromCode(*code);
@ -862,9 +853,7 @@ TEST(OverflowInstructions) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate, desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
t.lhs = ii;
t.rhs = jj;
@ -986,9 +975,8 @@ TEST(min_max_nan) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F3>::FromCode(*code);
for (int i = 0; i < kTableLength; i++) {
test.a = inputsa[i];
@ -1022,9 +1010,8 @@ bool run_Unaligned(char* memory_buffer, int32_t in_offset, int32_t out_offset,
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F_CVT>::FromCode(*code);
@ -1387,9 +1374,8 @@ bool run_Sltu(uint64_t rs, uint64_t rd, Func GenerateSltuInstructionFunc) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
auto f = GeneratedCode<F_CVT>::FromCode(*code);
int64_t res = reinterpret_cast<int64_t>(f.Call(rs, rd, 0, 0, 0));
@ -1483,8 +1469,7 @@ static GeneratedCode<F4> GenerateMacroFloat32MinMax(MacroAssembler* masm) {
CodeDesc desc;
masm->GetCode(masm->isolate(), &desc);
Handle<Code> code =
Factory::CodeBuilder(masm->isolate(), desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
Factory::CodeBuilder(masm->isolate(), desc, CodeKind::FOR_TESTING)
.Build();
#ifdef DEBUG
StdoutStream os;
@ -1626,8 +1611,7 @@ static GeneratedCode<F4> GenerateMacroFloat64MinMax(MacroAssembler* masm) {
CodeDesc desc;
masm->GetCode(masm->isolate(), &desc);
Handle<Code> code =
Factory::CodeBuilder(masm->isolate(), desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
Factory::CodeBuilder(masm->isolate(), desc, CodeKind::FOR_TESTING)
.Build();
#ifdef DEBUG
StdoutStream os;

View File

@ -27,13 +27,13 @@
#include <stdlib.h>
#include "src/init/v8.h"
#include "src/base/platform/platform.h"
#include "src/codegen/macro-assembler.h"
#include "src/codegen/x64/assembler-x64-inl.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/execution/simulator.h"
#include "src/heap/factory.h"
#include "src/init/v8.h"
#include "src/objects/objects-inl.h"
#include "src/objects/smi.h"
#include "src/utils/ostreams.h"
@ -449,9 +449,8 @@ TEST(EmbeddedObj) {
CodeDesc desc;
masm->GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
#ifdef OBJECT_PRINT
StdoutStream os;
code->Print(os);
@ -1034,6 +1033,29 @@ TEST(AreAliased) {
DCHECK(AreAliased(rax, no_reg, rbx, no_reg, rcx, no_reg, rdx, rax, no_reg));
}
TEST(DeoptExitSizeIsFixed) {
CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate, v8::internal::CodeObjectRequired::kYes,
buffer->CreateView());
STATIC_ASSERT(static_cast<int>(kFirstDeoptimizeKind) == 0);
for (int i = 0; i < kDeoptimizeKindCount; i++) {
DeoptimizeKind kind = static_cast<DeoptimizeKind>(i);
Builtins::Name target = Deoptimizer::GetDeoptimizationEntry(isolate, kind);
Label before_exit;
masm.bind(&before_exit);
masm.CallForDeoptimization(target, 42, &before_exit, kind, nullptr);
CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit),
kind == DeoptimizeKind::kLazy
? Deoptimizer::kLazyDeoptExitSize
: Deoptimizer::kNonLazyDeoptExitSize);
}
}
#undef __
} // namespace test_macro_assembler_x64

View File

@ -204,9 +204,8 @@ void TestInvalidateExclusiveAccess(TestData initial_data, MemoryAccess access1,
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
TestData t = initial_data;
Simulator::current(isolate)->Call<void>(code->entry(), &t);
@ -277,9 +276,8 @@ int ExecuteMemoryAccess(Isolate* isolate, TestData* test_data,
CodeDesc desc;
masm.GetCode(isolate, &desc);
Handle<Code> code = Factory::CodeBuilder(
isolate, desc, CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Handle<Code> code =
Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build();
Simulator::current(isolate)->Call<void>(code->entry(), test_data);
return Simulator::current(isolate)->wreg(0);
}

View File

@ -240,7 +240,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
callee.Return(static_cast<int>(desc->ReturnCount()), returns.get());
OptimizedCompilationInfo info(ArrayVector("testing"), &zone,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING);
CodeKind::FOR_TESTING);
Handle<Code> code =
Pipeline::GenerateCodeForTesting(&info, i_isolate, desc, callee.graph(),
AssemblerOptions::Default(i_isolate),
@ -286,7 +286,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Call the wrapper.
OptimizedCompilationInfo wrapper_info(ArrayVector("wrapper"), &zone,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING);
CodeKind::FOR_TESTING);
Handle<Code> wrapper_code =
Pipeline::GenerateCodeForTesting(
&wrapper_info, i_isolate, wrapper_desc, caller.graph(),

View File

@ -155,9 +155,7 @@ TEST_P(TurboAssemblerTestMoveObjectAndSlot, MoveObjectAndSlot) {
tasm.GetCode(nullptr, &desc);
if (FLAG_print_code) {
Handle<Code> code =
Factory::CodeBuilder(isolate(), desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate(), desc, CodeKind::FOR_TESTING).Build();
StdoutStream os;
code->Print(os);
}

View File

@ -161,9 +161,7 @@ TEST_P(TurboAssemblerTestMoveObjectAndSlot, MoveObjectAndSlot) {
tasm.GetCode(nullptr, &desc);
if (FLAG_print_code) {
Handle<Code> code =
Factory::CodeBuilder(isolate(), desc,
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING)
.Build();
Factory::CodeBuilder(isolate(), desc, CodeKind::FOR_TESTING).Build();
StdoutStream os;
code->Print(os);
}

View File

@ -24,7 +24,7 @@ CodeStubAssemblerTestState::CodeStubAssemblerTestState(
CodeStubAssemblerTest* test)
: compiler::CodeAssemblerState(
test->isolate(), test->zone(), VoidDescriptor{},
CodeKind::DEOPT_ENTRIES_OR_FOR_TESTING, "test",
CodeKind::FOR_TESTING, "test",
PoisoningMitigationLevel::kPoisonCriticalOnly) {}
TARGET_TEST_F(CodeStubAssemblerTest, SmiTag) {