Commit 1902b5a9 authored by Anisha Rohra's avatar Anisha Rohra Committed by Commit Bot

s390/PPC: Remove weak-list of optimized JS functions.

Port f0acede9

This CL removes the weak-list of JS functions from the context
and all the code that iterares over it. This list was being used
mainly during deoptimization (for code unlinking) and during
garbage collection. Removing it will improve performance of
programs that create many closures and trigger many scavenge GC
cycles.

No extra work is required during garbage collection. However,
given that we no longer unlink code from JS functions during
deoptimization, we leave it as it is, and on its next activation
we check whether the mark_for_deoptimization bit of that code is
set, and if it is, than we unlink it and jump to lazy compiled
code. This check happens in the prologue of every code object.

We needed to change/remove the cctests that used to check
something on this list.

R=bjaideep@ca.ibm.com, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=
LOG=N

Change-Id: I8007a837d43b6a339789cfd727e81ad7f4ac3ae1
Reviewed-on: https://chromium-review.googlesource.com/651891Reviewed-by: 's avatarJaideep Bajwa <bjaideep@ca.ibm.com>
Commit-Queue: Jaideep Bajwa <bjaideep@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#47840}
parent 8d7379c0
......@@ -977,7 +977,6 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
static void ReplaceClosureCodeWithOptimizedCode(
MacroAssembler* masm, Register optimized_code, Register closure,
Register scratch1, Register scratch2, Register scratch3) {
Register native_context = scratch1;
// Store code entry in the closure.
__ StoreP(optimized_code, FieldMemOperand(closure, JSFunction::kCodeOffset),
r0);
......@@ -985,29 +984,6 @@ static void ReplaceClosureCodeWithOptimizedCode(
__ RecordWriteField(closure, JSFunction::kCodeOffset, scratch1, scratch2,
kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
// Link the closure into the optimized function list.
// r7 : code entry
// r10: native context
// r4 : closure
__ LoadP(native_context, NativeContextMemOperand());
__ LoadP(scratch2, ContextMemOperand(native_context,
Context::OPTIMIZED_FUNCTIONS_LIST));
__ StoreP(scratch2,
FieldMemOperand(closure, JSFunction::kNextFunctionLinkOffset), r0);
__ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, scratch2,
scratch3, kLRHasNotBeenSaved, kDontSaveFPRegs,
EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
const int function_list_offset =
Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
__ StoreP(
closure,
ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST), r0);
// Save closure before the write barrier.
__ mr(scratch2, closure);
__ RecordWriteContextSlot(native_context, function_list_offset, closure,
scratch3, kLRHasNotBeenSaved, kDontSaveFPRegs);
__ mr(closure, scratch2);
}
static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
......@@ -1592,6 +1568,18 @@ void Builtins::Generate_CheckOptimizationMarker(MacroAssembler* masm) {
GenerateTailCallToSharedCode(masm);
}
void Builtins::Generate_CompileLazyDeoptimizedCode(MacroAssembler* masm) {
// Set the code slot inside the JSFunction to the trampoline to the
// interpreter entry.
__ LoadP(r5, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(r5, FieldMemOperand(r5, SharedFunctionInfo::kCodeOffset));
__ StoreP(r5, FieldMemOperand(r4, JSFunction::kCodeOffset), r0);
__ RecordWriteField(r4, JSFunction::kCodeOffset, r5, r7, kLRHasNotBeenSaved,
kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
// Jump to compile lazy.
Generate_CompileLazy(masm);
}
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : argument count (preserved for callee)
......
......@@ -976,7 +976,6 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
static void ReplaceClosureCodeWithOptimizedCode(
MacroAssembler* masm, Register optimized_code, Register closure,
Register scratch1, Register scratch2, Register scratch3) {
Register native_context = scratch1;
// Store code entry in the closure.
__ StoreP(optimized_code, FieldMemOperand(closure, JSFunction::kCodeOffset),
r0);
......@@ -985,29 +984,6 @@ static void ReplaceClosureCodeWithOptimizedCode(
__ RecordWriteField(closure, JSFunction::kCodeOffset, scratch1, scratch2,
kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
// Link the closure into the optimized function list.
// r6 : code entry
// r9: native context
// r3 : closure
__ LoadP(native_context, NativeContextMemOperand());
__ LoadP(scratch2, ContextMemOperand(native_context,
Context::OPTIMIZED_FUNCTIONS_LIST));
__ StoreP(scratch2,
FieldMemOperand(closure, JSFunction::kNextFunctionLinkOffset), r0);
__ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, scratch2,
scratch3, kLRHasNotBeenSaved, kDontSaveFPRegs,
EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
const int function_list_offset =
Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
__ StoreP(
closure,
ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST), r0);
// Save closure before the write barrier.
__ LoadRR(scratch2, closure);
__ RecordWriteContextSlot(native_context, function_list_offset, closure,
scratch3, kLRHasNotBeenSaved, kDontSaveFPRegs);
__ LoadRR(closure, scratch2);
}
static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
......@@ -1587,6 +1563,18 @@ void Builtins::Generate_CheckOptimizationMarker(MacroAssembler* masm) {
GenerateTailCallToSharedCode(masm);
}
void Builtins::Generate_CompileLazyDeoptimizedCode(MacroAssembler* masm) {
// Set the code slot inside the JSFunction to the trampoline to the
// interpreter entry.
__ LoadP(r4, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(r4, FieldMemOperand(r4, SharedFunctionInfo::kCodeOffset));
__ StoreP(r4, FieldMemOperand(r3, JSFunction::kCodeOffset));
__ RecordWriteField(r3, JSFunction::kCodeOffset, r4, r6, kLRHasNotBeenSaved,
kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
// Jump to compile lazy.
Generate_CompileLazy(masm);
}
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : argument count (preserved for callee)
......
......@@ -990,6 +990,27 @@ void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
first_unused_stack_slot);
}
// Check if the code object is marked for deoptimization. If it is, then it
// jumps to the CompileLazyDeoptimizedCode builtin. In order to do this we need
// to:
// 1. load the address of the current instruction;
// 2. read from memory the word that contains that bit, which can be found in
// the first set of flags ({kKindSpecificFlags1Offset});
// 3. test kMarkedForDeoptimizationBit in those flags; and
// 4. if it is not zero then it jumps to the builtin.
void CodeGenerator::BailoutIfDeoptimized() {
Label current;
__ mov_label_addr(r11, &current);
int pc_offset = __ pc_offset();
__ bind(&current);
int offset =
Code::kKindSpecificFlags1Offset - (Code::kHeaderSize + pc_offset);
__ LoadP(r11, MemOperand(r11, offset));
__ TestBit(r11, Code::kMarkedForDeoptimizationBit);
Handle<Code> code = isolate()->builtins()->builtin_handle(
Builtins::kCompileLazyDeoptimizedCode);
__ Jump(code, RelocInfo::CODE_TARGET, ne, cr0);
}
// Assembles an instruction after register allocation, producing machine code.
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
......
......@@ -1189,6 +1189,28 @@ void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
first_unused_stack_slot);
}
// Check if the code object is marked for deoptimization. If it is, then it
// jumps to the CompileLazyDeoptimizedCode builtin. In order to do this we need
// to:
// 1. load the address of the current instruction;
// 2. read from memory the word that contains that bit, which can be found in
// the first set of flags ({kKindSpecificFlags1Offset});
// 3. test kMarkedForDeoptimizationBit in those flags; and
// 4. if it is not zero then it jumps to the builtin.
void CodeGenerator::BailoutIfDeoptimized() {
Label current;
__ larl(r1, &current);
int pc_offset = __ pc_offset();
__ bind(&current);
int offset =
Code::kKindSpecificFlags1Offset - (Code::kHeaderSize + pc_offset);
__ LoadP(ip, MemOperand(r1, offset));
__ TestBit(ip, Code::kMarkedForDeoptimizationBit);
Handle<Code> code = isolate()->builtins()->builtin_handle(
Builtins::kCompileLazyDeoptimizedCode);
__ Jump(code, RelocInfo::CODE_TARGET, ne);
}
// Assembles an instruction after register allocation, producing machine code.
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) {
......
......@@ -136,10 +136,10 @@ void TurboAssembler::Jump(Address target, RelocInfo::Mode rmode, Condition cond,
}
void TurboAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode,
Condition cond) {
Condition cond, CRegister cr) {
DCHECK(RelocInfo::IsCodeTarget(rmode));
// 'code' is always generated ppc code, never THUMB code
Jump(reinterpret_cast<intptr_t>(code.address()), rmode, cond);
Jump(reinterpret_cast<intptr_t>(code.address()), rmode, cond, cr);
}
int TurboAssembler::CallSize(Register target) { return 2 * kInstrSize; }
......@@ -2923,7 +2923,7 @@ void TurboAssembler::StorePU(Register src, const MemOperand& mem,
}
}
void MacroAssembler::LoadWordArith(Register dst, const MemOperand& mem,
void TurboAssembler::LoadWordArith(Register dst, const MemOperand& mem,
Register scratch) {
int offset = mem.offset();
......
......@@ -199,6 +199,8 @@ class TurboAssembler : public Assembler {
// These exist to provide portability between 32 and 64bit
void LoadP(Register dst, const MemOperand& mem, Register scratch = no_reg);
void LoadPU(Register dst, const MemOperand& mem, Register scratch = no_reg);
void LoadWordArith(Register dst, const MemOperand& mem,
Register scratch = no_reg);
void StoreP(Register src, const MemOperand& mem, Register scratch = no_reg);
void StorePU(Register src, const MemOperand& mem, Register scratch = no_reg);
......@@ -415,7 +417,8 @@ class TurboAssembler : public Assembler {
void Jump(Register target);
void Jump(Address target, RelocInfo::Mode rmode, Condition cond = al,
CRegister cr = cr7);
void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al,
CRegister cr = cr7);
void Call(Register target);
void Call(Address target, RelocInfo::Mode rmode, Condition cond = al);
int CallSize(Handle<Code> code,
......@@ -789,8 +792,6 @@ class MacroAssembler : public TurboAssembler {
// load a literal double value <value> to FPR <result>
void LoadWord(Register dst, const MemOperand& mem, Register scratch);
void LoadWordArith(Register dst, const MemOperand& mem,
Register scratch = no_reg);
void StoreWord(Register src, const MemOperand& mem, Register scratch);
void LoadHalfWord(Register dst, const MemOperand& mem, Register scratch);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment