Version 5.2.7.1 (cherry-pick)
Merged f021b7ca8f41c22317df57896480f52b9a9f1bdc
Revert of Visit the Optimized Code Map on first call rather than closure creation. (patchset #7 id:120001 of https://codereview.chromium.org/1670143002/ )
TBR=mvstanton@chromium.org
BUG=
Review URL: https://codereview.chromium.org/1881743003 .
Cr-Commit-Position: refs/heads/5.2.7@{#2}
Cr-Branched-From: 58429beb7b030805197c8968bcae4b2c20127804-refs/heads/master@{#35397}
diff --git a/include/v8-version.h b/include/v8-version.h
index e47acba..f2cc038 100644
--- a/include/v8-version.h
+++ b/include/v8-version.h
@@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 5
#define V8_MINOR_VERSION 2
#define V8_BUILD_NUMBER 7
-#define V8_PATCH_LEVEL 0
+#define V8_PATCH_LEVEL 1
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index cd3a926..74fd005 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -1228,159 +1228,6 @@
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- r0 : argument count (preserved for callee)
- // -- r3 : new target (preserved for callee)
- // -- r1 : target function (preserved for callee)
- // -----------------------------------
- // First lookup code, maybe we don't need to compile!
- Label gotta_call_runtime, gotta_call_runtime_no_stack;
- Label maybe_call_runtime;
- Label try_shared;
- Label loop_top, loop_bottom;
-
- Register argument_count = r0;
- Register closure = r1;
- Register new_target = r3;
- __ push(argument_count);
- __ push(new_target);
- __ push(closure);
-
- Register map = argument_count;
- Register index = r2;
- __ ldr(map, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ ldr(map,
- FieldMemOperand(map, SharedFunctionInfo::kOptimizedCodeMapOffset));
- __ ldr(index, FieldMemOperand(map, FixedArray::kLengthOffset));
- __ cmp(index, Operand(Smi::FromInt(2)));
- __ b(lt, &gotta_call_runtime);
-
- // Find literals.
- // r3 : native context
- // r2 : length / index
- // r0 : optimized code map
- // stack[0] : new target
- // stack[4] : closure
- Register native_context = r3;
- __ ldr(native_context, NativeContextMemOperand());
-
- __ bind(&loop_top);
- Register temp = r1;
- Register array_pointer = r5;
-
- // Does the native context match?
- __ add(array_pointer, map, Operand::PointerOffsetFromSmiKey(index));
- __ ldr(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousContext));
- __ ldr(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
- __ cmp(temp, native_context);
- __ b(ne, &loop_bottom);
- // OSR id set to none?
- __ ldr(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousOsrAstId));
- const int bailout_id = BailoutId::None().ToInt();
- __ cmp(temp, Operand(Smi::FromInt(bailout_id)));
- __ b(ne, &loop_bottom);
- // Literals available?
- __ ldr(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousLiterals));
- __ ldr(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
- __ JumpIfSmi(temp, &gotta_call_runtime);
-
- // Save the literals in the closure.
- __ ldr(r4, MemOperand(sp, 0));
- __ str(temp, FieldMemOperand(r4, JSFunction::kLiteralsOffset));
- __ push(index);
- __ RecordWriteField(r4, JSFunction::kLiteralsOffset, temp, index,
- kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- __ pop(index);
-
- // Code available?
- Register entry = r4;
- __ ldr(entry,
- FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousCachedCode));
- __ ldr(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &maybe_call_runtime);
-
- // Found literals and code. Get them into the closure and return.
- __ pop(closure);
- // Store code entry in the closure.
- __ add(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
-
- Label install_optimized_code_and_tailcall;
- __ bind(&install_optimized_code_and_tailcall);
- __ str(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
- __ RecordWriteCodeEntryField(closure, entry, r5);
-
- // Link the closure into the optimized function list.
- // r4 : code entry
- // r3 : native context
- // r1 : closure
- __ ldr(r5,
- ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
- __ str(r5, FieldMemOperand(closure, JSFunction::kNextFunctionLinkOffset));
- __ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, r5, r0,
- kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- const int function_list_offset =
- Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
- __ str(closure,
- ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
- // Save closure before the write barrier.
- __ mov(r5, closure);
- __ RecordWriteContextSlot(native_context, function_list_offset, closure, r0,
- kLRHasNotBeenSaved, kDontSaveFPRegs);
- __ mov(closure, r5);
- __ pop(new_target);
- __ pop(argument_count);
- __ Jump(entry);
-
- __ bind(&loop_bottom);
- __ sub(index, index, Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
- __ cmp(index, Operand(Smi::FromInt(1)));
- __ b(gt, &loop_top);
-
- // We found neither literals nor code.
- __ jmp(&gotta_call_runtime);
-
- __ bind(&maybe_call_runtime);
- __ pop(closure);
-
- // Last possibility. Check the context free optimized code map entry.
- __ ldr(entry, FieldMemOperand(map, FixedArray::kHeaderSize +
- SharedFunctionInfo::kSharedCodeIndex));
- __ ldr(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &try_shared);
-
- // Store code entry in the closure.
- __ add(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ jmp(&install_optimized_code_and_tailcall);
-
- __ bind(&try_shared);
- __ pop(new_target);
- __ pop(argument_count);
- // Is the full code valid?
- __ ldr(entry,
- FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ ldr(entry, FieldMemOperand(entry, SharedFunctionInfo::kCodeOffset));
- __ ldr(r5, FieldMemOperand(entry, Code::kFlagsOffset));
- __ and_(r5, r5, Operand(Code::KindField::kMask));
- __ mov(r5, Operand(r5, LSR, Code::KindField::kShift));
- __ cmp(r5, Operand(Code::BUILTIN));
- __ b(eq, &gotta_call_runtime_no_stack);
- // Yes, install the full code.
- __ add(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ str(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
- __ RecordWriteCodeEntryField(closure, entry, r5);
- __ Jump(entry);
-
- __ bind(&gotta_call_runtime);
- __ pop(closure);
- __ pop(new_target);
- __ pop(argument_count);
- __ bind(&gotta_call_runtime_no_stack);
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
diff --git a/src/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc
index e790ba3..4ed33a0 100644
--- a/src/arm64/builtins-arm64.cc
+++ b/src/arm64/builtins-arm64.cc
@@ -1177,138 +1177,6 @@
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- x0 : argument count (preserved for callee)
- // -- x3 : new target (preserved for callee)
- // -- x1 : target function (preserved for callee)
- // -----------------------------------
- // First lookup code, maybe we don't need to compile!
- Label gotta_call_runtime;
- Label maybe_call_runtime;
- Label try_shared;
- Label loop_top, loop_bottom;
-
- Register closure = x1;
- Register new_target = x3;
- Register map = x13;
- Register index = x2;
- __ Ldr(map, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ Ldr(map,
- FieldMemOperand(map, SharedFunctionInfo::kOptimizedCodeMapOffset));
- __ Ldrsw(index, UntagSmiFieldMemOperand(map, FixedArray::kLengthOffset));
- __ Cmp(index, Operand(2));
- __ B(lt, &gotta_call_runtime);
-
- // Find literals.
- // x3 : native context
- // x2 : length / index
- // x13 : optimized code map
- // stack[0] : new target
- // stack[4] : closure
- Register native_context = x4;
- __ Ldr(native_context, NativeContextMemOperand());
-
- __ Bind(&loop_top);
- Register temp = x5;
- Register array_pointer = x6;
-
- // Does the native context match?
- __ Add(array_pointer, map, Operand(index, LSL, kPointerSizeLog2));
- __ Ldr(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousContext));
- __ Ldr(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
- __ Cmp(temp, native_context);
- __ B(ne, &loop_bottom);
- // OSR id set to none?
- __ Ldr(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousOsrAstId));
- const int bailout_id = BailoutId::None().ToInt();
- __ Cmp(temp, Operand(Smi::FromInt(bailout_id)));
- __ B(ne, &loop_bottom);
- // Literals available?
- __ Ldr(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousLiterals));
- __ Ldr(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
- __ JumpIfSmi(temp, &gotta_call_runtime);
-
- // Save the literals in the closure.
- __ Str(temp, FieldMemOperand(closure, JSFunction::kLiteralsOffset));
- __ RecordWriteField(closure, JSFunction::kLiteralsOffset, temp, x7,
- kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
-
- // Code available?
- Register entry = x7;
- __ Ldr(entry,
- FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousCachedCode));
- __ Ldr(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &maybe_call_runtime);
-
- // Found literals and code. Get them into the closure and return.
- __ Add(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
-
- Label install_optimized_code_and_tailcall;
- __ Bind(&install_optimized_code_and_tailcall);
- __ Str(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
- __ RecordWriteCodeEntryField(closure, entry, x5);
-
- // Link the closure into the optimized function list.
- // x7 : code entry
- // x4 : native context
- // x1 : closure
- __ Ldr(x8,
- ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
- __ Str(x8, FieldMemOperand(closure, JSFunction::kNextFunctionLinkOffset));
- __ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, x8, x13,
- kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- const int function_list_offset =
- Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
- __ Str(closure,
- ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
- __ Mov(x5, closure);
- __ RecordWriteContextSlot(native_context, function_list_offset, x5, x13,
- kLRHasNotBeenSaved, kDontSaveFPRegs);
- __ Jump(entry);
-
- __ Bind(&loop_bottom);
- __ Sub(index, index, Operand(SharedFunctionInfo::kEntryLength));
- __ Cmp(index, Operand(1));
- __ B(gt, &loop_top);
-
- // We found neither literals nor code.
- __ B(&gotta_call_runtime);
-
- __ Bind(&maybe_call_runtime);
-
- // Last possibility. Check the context free optimized code map entry.
- __ Ldr(entry, FieldMemOperand(map, FixedArray::kHeaderSize +
- SharedFunctionInfo::kSharedCodeIndex));
- __ Ldr(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &try_shared);
-
- // Store code entry in the closure.
- __ Add(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ B(&install_optimized_code_and_tailcall);
-
- __ Bind(&try_shared);
- // Is the full code valid?
- __ Ldr(entry,
- FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ Ldr(entry, FieldMemOperand(entry, SharedFunctionInfo::kCodeOffset));
- __ Ldr(x5, FieldMemOperand(entry, Code::kFlagsOffset));
- __ and_(x5, x5, Operand(Code::KindField::kMask));
- __ Mov(x5, Operand(x5, LSR, Code::KindField::kShift));
- __ Cmp(x5, Operand(Code::BUILTIN));
- __ B(eq, &gotta_call_runtime);
- // Yes, install the full code.
- __ Add(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ Str(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
- __ RecordWriteCodeEntryField(closure, entry, x5);
- __ Jump(entry);
-
- __ Bind(&gotta_call_runtime);
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index d59712c..1d2fb81 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -97,6 +97,26 @@
HValue* BuildInternalArrayConstructor(ElementsKind kind,
ArgumentClass argument_class);
+ // BuildCheckAndInstallOptimizedCode emits code to install the optimized
+ // function found in the optimized code map at map_index in js_function, if
+ // the function at map_index matches the given native_context. Builder is
+ // left in the "Then()" state after the install.
+ void BuildCheckAndInstallOptimizedCode(HValue* js_function,
+ HValue* native_context,
+ IfBuilder* builder,
+ HValue* optimized_map,
+ HValue* map_index);
+ void BuildInstallOptimizedCode(HValue* js_function, HValue* native_context,
+ HValue* code_object, HValue* literals);
+ void BuildInstallCode(HValue* js_function, HValue* shared_info);
+
+ HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map,
+ HValue* iterator,
+ int field_offset);
+ void BuildInstallFromOptimizedCodeMap(HValue* js_function,
+ HValue* shared_info,
+ HValue* native_context);
+
HValue* BuildToString(HValue* input, bool convert);
HValue* BuildToPrimitive(HValue* input, HValue* input_map);
@@ -1993,6 +2013,182 @@
Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); }
+void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode(
+ HValue* js_function,
+ HValue* native_context,
+ IfBuilder* builder,
+ HValue* optimized_map,
+ HValue* map_index) {
+ HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt());
+ HValue* context_slot = LoadFromOptimizedCodeMap(
+ optimized_map, map_index, SharedFunctionInfo::kContextOffset);
+ context_slot = Add<HLoadNamedField>(context_slot, nullptr,
+ HObjectAccess::ForWeakCellValue());
+ HValue* osr_ast_slot = LoadFromOptimizedCodeMap(
+ optimized_map, map_index, SharedFunctionInfo::kOsrAstIdOffset);
+ HValue* code_object = LoadFromOptimizedCodeMap(
+ optimized_map, map_index, SharedFunctionInfo::kCachedCodeOffset);
+ code_object = Add<HLoadNamedField>(code_object, nullptr,
+ HObjectAccess::ForWeakCellValue());
+ builder->If<HCompareObjectEqAndBranch>(native_context,
+ context_slot);
+ builder->AndIf<HCompareObjectEqAndBranch>(osr_ast_slot, osr_ast_id_none);
+ builder->And();
+ builder->IfNot<HCompareObjectEqAndBranch>(code_object,
+ graph()->GetConstant0());
+ builder->Then();
+ HValue* literals = LoadFromOptimizedCodeMap(optimized_map,
+ map_index, SharedFunctionInfo::kLiteralsOffset);
+ literals = Add<HLoadNamedField>(literals, nullptr,
+ HObjectAccess::ForWeakCellValue());
+ IfBuilder maybe_deopt(this);
+ maybe_deopt.If<HCompareObjectEqAndBranch>(literals, graph()->GetConstant0());
+ maybe_deopt.ThenDeopt(Deoptimizer::kLiteralsWereDisposed);
+ maybe_deopt.End();
+
+ BuildInstallOptimizedCode(js_function, native_context, code_object, literals);
+
+ // The builder continues in the "then" after this function.
+}
+
+
+void CodeStubGraphBuilderBase::BuildInstallOptimizedCode(HValue* js_function,
+ HValue* native_context,
+ HValue* code_object,
+ HValue* literals) {
+ Counters* counters = isolate()->counters();
+ AddIncrementCounter(counters->fast_new_closure_install_optimized());
+
+ // TODO(fschneider): Idea: store proper code pointers in the optimized code
+ // map and either unmangle them on marking or do nothing as the whole map is
+ // discarded on major GC anyway.
+ Add<HStoreCodeEntry>(js_function, code_object);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
+ literals);
+
+ // Now link a function into a list of optimized functions.
+ HValue* optimized_functions_list = Add<HLoadNamedField>(
+ native_context, nullptr,
+ HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
+ Add<HStoreNamedField>(js_function,
+ HObjectAccess::ForNextFunctionLinkPointer(),
+ optimized_functions_list);
+
+ // This store is the only one that should have a write barrier.
+ Add<HStoreNamedField>(native_context,
+ HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
+ js_function);
+}
+
+
+void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
+ HValue* shared_info) {
+ Add<HStoreNamedField>(js_function,
+ HObjectAccess::ForNextFunctionLinkPointer(),
+ graph()->GetConstantUndefined());
+ HValue* code_object = Add<HLoadNamedField>(shared_info, nullptr,
+ HObjectAccess::ForCodeOffset());
+ Add<HStoreCodeEntry>(js_function, code_object);
+}
+
+
+HInstruction* CodeStubGraphBuilderBase::LoadFromOptimizedCodeMap(
+ HValue* optimized_map,
+ HValue* iterator,
+ int field_offset) {
+ // By making sure to express these loads in the form [<hvalue> + constant]
+ // the keyed load can be hoisted.
+ DCHECK(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength);
+ HValue* field_slot = iterator;
+ if (field_offset > 0) {
+ HValue* field_offset_value = Add<HConstant>(field_offset);
+ field_slot = AddUncasted<HAdd>(iterator, field_offset_value);
+ }
+ HInstruction* field_entry = Add<HLoadKeyed>(optimized_map, field_slot,
+ nullptr, nullptr, FAST_ELEMENTS);
+ return field_entry;
+}
+
+
+void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
+ HValue* js_function,
+ HValue* shared_info,
+ HValue* native_context) {
+ Counters* counters = isolate()->counters();
+ Factory* factory = isolate()->factory();
+ IfBuilder is_optimized(this);
+ HInstruction* optimized_map = Add<HLoadNamedField>(
+ shared_info, nullptr, HObjectAccess::ForOptimizedCodeMap());
+ HValue* null_constant = Add<HConstant>(0);
+ is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant);
+ is_optimized.Then();
+ {
+ BuildInstallCode(js_function, shared_info);
+ }
+ is_optimized.Else();
+ {
+ AddIncrementCounter(counters->fast_new_closure_try_optimized());
+ // The {optimized_map} points to fixed array of 4-element entries:
+ // (native context, optimized code, literals, ast-id).
+ // Iterate through the {optimized_map} backwards. After the loop, if no
+ // matching optimized code was found, install unoptimized code.
+ // for(i = map.length() - SharedFunctionInfo::kEntryLength;
+ // i >= SharedFunctionInfo::kEntriesStart;
+ // i -= SharedFunctionInfo::kEntryLength) { ... }
+ HValue* first_entry_index =
+ Add<HConstant>(SharedFunctionInfo::kEntriesStart);
+ HValue* shared_function_entry_length =
+ Add<HConstant>(SharedFunctionInfo::kEntryLength);
+ LoopBuilder loop_builder(this, context(), LoopBuilder::kPostDecrement,
+ shared_function_entry_length);
+ HValue* array_length = Add<HLoadNamedField>(
+ optimized_map, nullptr, HObjectAccess::ForFixedArrayLength());
+ HValue* start_pos =
+ AddUncasted<HSub>(array_length, shared_function_entry_length);
+ HValue* slot_iterator =
+ loop_builder.BeginBody(start_pos, first_entry_index, Token::GTE);
+ {
+ IfBuilder done_check(this);
+ BuildCheckAndInstallOptimizedCode(js_function, native_context,
+ &done_check, optimized_map,
+ slot_iterator);
+ // Fall out of the loop
+ loop_builder.Break();
+ }
+ loop_builder.EndBody();
+
+ // If {slot_iterator} is less than the first entry index, then we failed to
+ // find a context-dependent code and try context-independent code next.
+ IfBuilder no_optimized_code_check(this);
+ no_optimized_code_check.If<HCompareNumericAndBranch>(
+ slot_iterator, first_entry_index, Token::LT);
+ no_optimized_code_check.Then();
+ {
+ IfBuilder shared_code_check(this);
+ HValue* shared_code =
+ Add<HLoadNamedField>(optimized_map, nullptr,
+ HObjectAccess::ForOptimizedCodeMapSharedCode());
+ shared_code = Add<HLoadNamedField>(shared_code, nullptr,
+ HObjectAccess::ForWeakCellValue());
+ shared_code_check.IfNot<HCompareObjectEqAndBranch>(
+ shared_code, graph()->GetConstant0());
+ shared_code_check.Then();
+ {
+ // Store the context-independent optimized code.
+ HValue* literals = Add<HConstant>(factory->empty_fixed_array());
+ BuildInstallOptimizedCode(js_function, native_context, shared_code,
+ literals);
+ }
+ shared_code_check.Else();
+ {
+ // Store the unoptimized code.
+ BuildInstallCode(js_function, shared_info);
+ }
+ }
+ }
+}
+
+
template<>
HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
Counters* counters = isolate()->counters();
@@ -2032,13 +2228,10 @@
Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
context());
- Handle<Code> lazy_builtin(
- isolate()->builtins()->builtin(Builtins::kCompileLazy));
- HConstant* lazy = Add<HConstant>(lazy_builtin);
- Add<HStoreCodeEntry>(js_function, lazy);
- Add<HStoreNamedField>(js_function,
- HObjectAccess::ForNextFunctionLinkPointer(),
- graph()->GetConstantUndefined());
+ // Initialize the code pointer in the function to be the one found in the
+ // shared function info object. But first check if there is an optimized
+ // version for our context.
+ BuildInstallFromOptimizedCodeMap(js_function, shared_info, native_context);
return js_function;
}
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index a02e947..1acd977 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -3688,7 +3688,11 @@
return VectorStoreTransitionDescriptor(isolate());
}
-void FastNewClosureStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {}
+
+void FastNewClosureStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
+ descriptor->Initialize(Runtime::FunctionForId(Runtime::kNewClosure)->entry);
+}
+
void FastNewContextStub::InitializeDescriptor(CodeStubDescriptor* d) {}
diff --git a/src/compiler.cc b/src/compiler.cc
index f42d8b9..205a85e 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -891,16 +891,6 @@
TimerEventScope<TimerEventCompileCode> compile_timer(isolate);
TRACE_EVENT0("v8", "V8.CompileCode");
AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy());
-
- if (FLAG_turbo_cache_shared_code) {
- CodeAndLiterals result;
- result = function->shared()->SearchOptimizedCodeMap(
- *isolate->native_context(), BailoutId::None());
- if (result.code != nullptr) {
- return Handle<Code>(result.code);
- }
- }
-
// If the debugger is active, do not compile with turbofan unless we can
// deopt from turbofan code.
if (FLAG_turbo_asm && function->shared()->asm_function() &&
@@ -1131,7 +1121,6 @@
bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) {
if (function->is_compiled()) return true;
-
MaybeHandle<Code> maybe_code = GetLazyCode(function);
Handle<Code> code;
if (!maybe_code.ToHandle(&code)) {
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 4f331c2..16a2b32 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -842,154 +842,6 @@
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- eax : argument count (preserved for callee)
- // -- edx : new target (preserved for callee)
- // -- edi : target function (preserved for callee)
- // -----------------------------------
- // First lookup code, maybe we don't need to compile!
- Label gotta_call_runtime, gotta_call_runtime_no_stack;
- Label maybe_call_runtime;
- Label try_shared;
- Label loop_top, loop_bottom;
-
- Register closure = edi;
- Register new_target = edx;
- Register argument_count = eax;
-
- __ push(argument_count);
- __ push(new_target);
- __ push(closure);
-
- Register map = argument_count;
- Register index = ebx;
- __ mov(map, FieldOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ mov(map, FieldOperand(map, SharedFunctionInfo::kOptimizedCodeMapOffset));
- __ mov(index, FieldOperand(map, FixedArray::kLengthOffset));
- __ cmp(index, Immediate(Smi::FromInt(2)));
- __ j(less, &gotta_call_runtime);
-
- // Find literals.
- // edx : native context
- // ebx : length / index
- // eax : optimized code map
- // stack[0] : new target
- // stack[4] : closure
- Register native_context = edx;
- __ mov(native_context, NativeContextOperand());
-
- __ bind(&loop_top);
- Register temp = edi;
-
- // Does the native context match?
- __ mov(temp, FieldOperand(map, index, times_half_pointer_size,
- SharedFunctionInfo::kOffsetToPreviousContext));
- __ mov(temp, FieldOperand(temp, WeakCell::kValueOffset));
- __ cmp(temp, native_context);
- __ j(not_equal, &loop_bottom);
- // OSR id set to none?
- __ mov(temp, FieldOperand(map, index, times_half_pointer_size,
- SharedFunctionInfo::kOffsetToPreviousOsrAstId));
- const int bailout_id = BailoutId::None().ToInt();
- __ cmp(temp, Immediate(Smi::FromInt(bailout_id)));
- __ j(not_equal, &loop_bottom);
- // Literals available?
- __ mov(temp, FieldOperand(map, index, times_half_pointer_size,
- SharedFunctionInfo::kOffsetToPreviousLiterals));
- __ mov(temp, FieldOperand(temp, WeakCell::kValueOffset));
- __ JumpIfSmi(temp, &gotta_call_runtime);
-
- // Save the literals in the closure.
- __ mov(ecx, Operand(esp, 0));
- __ mov(FieldOperand(ecx, JSFunction::kLiteralsOffset), temp);
- __ push(index);
- __ RecordWriteField(ecx, JSFunction::kLiteralsOffset, temp, index,
- kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
- __ pop(index);
-
- // Code available?
- Register entry = ecx;
- __ mov(entry, FieldOperand(map, index, times_half_pointer_size,
- SharedFunctionInfo::kOffsetToPreviousCachedCode));
- __ mov(entry, FieldOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &maybe_call_runtime);
-
- // Found literals and code. Get them into the closure and return.
- __ pop(closure);
- // Store code entry in the closure.
- __ lea(entry, FieldOperand(entry, Code::kHeaderSize));
-
- Label install_optimized_code_and_tailcall;
- __ bind(&install_optimized_code_and_tailcall);
- __ mov(FieldOperand(closure, JSFunction::kCodeEntryOffset), entry);
- __ RecordWriteCodeEntryField(closure, entry, eax);
-
- // Link the closure into the optimized function list.
- // ecx : code entry
- // edx : native context
- // edi : closure
- __ mov(ebx,
- ContextOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
- __ mov(FieldOperand(closure, JSFunction::kNextFunctionLinkOffset), ebx);
- __ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, ebx, eax,
- kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
- const int function_list_offset =
- Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
- __ mov(ContextOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST),
- closure);
- // Save closure before the write barrier.
- __ mov(ebx, closure);
- __ RecordWriteContextSlot(native_context, function_list_offset, closure, eax,
- kDontSaveFPRegs);
- __ mov(closure, ebx);
- __ pop(new_target);
- __ pop(argument_count);
- __ jmp(entry);
-
- __ bind(&loop_bottom);
- __ sub(index, Immediate(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
- __ cmp(index, Immediate(Smi::FromInt(1)));
- __ j(greater, &loop_top);
-
- // We found neither literals nor code.
- __ jmp(&gotta_call_runtime);
-
- __ bind(&maybe_call_runtime);
- __ pop(closure);
-
- // Last possibility. Check the context free optimized code map entry.
- __ mov(entry, FieldOperand(map, FixedArray::kHeaderSize +
- SharedFunctionInfo::kSharedCodeIndex));
- __ mov(entry, FieldOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &try_shared);
-
- // Store code entry in the closure.
- __ lea(entry, FieldOperand(entry, Code::kHeaderSize));
- __ jmp(&install_optimized_code_and_tailcall);
-
- __ bind(&try_shared);
- __ pop(new_target);
- __ pop(argument_count);
- // Is the full code valid?
- __ mov(entry, FieldOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ mov(entry, FieldOperand(entry, SharedFunctionInfo::kCodeOffset));
- __ mov(ebx, FieldOperand(entry, Code::kFlagsOffset));
- __ and_(ebx, Code::KindField::kMask);
- __ shr(ebx, Code::KindField::kShift);
- __ cmp(ebx, Immediate(Code::BUILTIN));
- __ j(equal, &gotta_call_runtime_no_stack);
- // Yes, install the full code.
- __ lea(entry, FieldOperand(entry, Code::kHeaderSize));
- __ mov(FieldOperand(closure, JSFunction::kCodeEntryOffset), entry);
- __ RecordWriteCodeEntryField(closure, entry, ebx);
- __ jmp(entry);
-
- __ bind(&gotta_call_runtime);
- __ pop(closure);
- __ pop(new_target);
- __ pop(argument_count);
- __ bind(&gotta_call_runtime_no_stack);
-
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index b26616a..081c1af 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -1226,154 +1226,6 @@
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- a0 : argument count (preserved for callee)
- // -- a3 : new target (preserved for callee)
- // -- a1 : target function (preserved for callee)
- // -----------------------------------
- // First lookup code, maybe we don't need to compile!
- Label gotta_call_runtime, gotta_call_runtime_no_stack;
- Label maybe_call_runtime;
- Label try_shared;
- Label loop_top, loop_bottom;
-
- Register argument_count = a0;
- Register closure = a1;
- Register new_target = a3;
- __ push(argument_count);
- __ push(new_target);
- __ push(closure);
-
- Register map = a0;
- Register index = a2;
- __ lw(map, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ lw(map, FieldMemOperand(map, SharedFunctionInfo::kOptimizedCodeMapOffset));
- __ lw(index, FieldMemOperand(map, FixedArray::kLengthOffset));
- __ Branch(&gotta_call_runtime, lt, index, Operand(Smi::FromInt(2)));
-
- // Find literals.
- // a3 : native context
- // a2 : length / index
- // a0 : optimized code map
- // stack[0] : new target
- // stack[4] : closure
- Register native_context = a3;
- __ lw(native_context, NativeContextMemOperand());
-
- __ bind(&loop_top);
- Register temp = a1;
- Register array_pointer = t1;
-
- // Does the native context match?
- __ sll(at, index, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(array_pointer, map, Operand(at));
- __ lw(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousContext));
- __ lw(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
- __ Branch(&loop_bottom, ne, temp, Operand(native_context));
- // OSR id set to none?
- __ lw(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousOsrAstId));
- const int bailout_id = BailoutId::None().ToInt();
- __ Branch(&loop_bottom, ne, temp, Operand(Smi::FromInt(bailout_id)));
- // Literals available?
- __ lw(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousLiterals));
- __ lw(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
- __ JumpIfSmi(temp, &gotta_call_runtime);
-
- // Save the literals in the closure.
- __ lw(t0, MemOperand(sp, 0));
- __ sw(temp, FieldMemOperand(t0, JSFunction::kLiteralsOffset));
- __ push(index);
- __ RecordWriteField(t0, JSFunction::kLiteralsOffset, temp, index,
- kRAHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- __ pop(index);
-
- // Code available?
- Register entry = t0;
- __ lw(entry,
- FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousCachedCode));
- __ lw(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &maybe_call_runtime);
-
- // Found literals and code. Get them into the closure and return.
- __ pop(closure);
- // Store code entry in the closure.
- __ Addu(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
-
- Label install_optimized_code_and_tailcall;
- __ bind(&install_optimized_code_and_tailcall);
- __ sw(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
- __ RecordWriteCodeEntryField(closure, entry, t1);
-
- // Link the closure into the optimized function list.
- // t0 : code entry
- // a3 : native context
- // a1 : closure
- __ lw(t1,
- ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
- __ sw(t1, FieldMemOperand(closure, JSFunction::kNextFunctionLinkOffset));
- __ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, t1, a0,
- kRAHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- const int function_list_offset =
- Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
- __ sw(closure,
- ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
- // Save closure before the write barrier.
- __ mov(t1, closure);
- __ RecordWriteContextSlot(native_context, function_list_offset, closure, a0,
- kRAHasNotBeenSaved, kDontSaveFPRegs);
- __ mov(closure, t1);
- __ pop(new_target);
- __ pop(argument_count);
- __ Jump(entry);
-
- __ bind(&loop_bottom);
- __ Subu(index, index,
- Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
- __ Branch(&loop_top, gt, index, Operand(Smi::FromInt(1)));
-
- // We found neither literals nor code.
- __ jmp(&gotta_call_runtime);
-
- __ bind(&maybe_call_runtime);
- __ pop(closure);
-
- // Last possibility. Check the context free optimized code map entry.
- __ lw(entry, FieldMemOperand(map, FixedArray::kHeaderSize +
- SharedFunctionInfo::kSharedCodeIndex));
- __ lw(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &try_shared);
-
- // Store code entry in the closure.
- __ Addu(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ jmp(&install_optimized_code_and_tailcall);
-
- __ bind(&try_shared);
- __ pop(new_target);
- __ pop(argument_count);
- // Is the full code valid?
- __ lw(entry, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ lw(entry, FieldMemOperand(entry, SharedFunctionInfo::kCodeOffset));
- __ lw(t1, FieldMemOperand(entry, Code::kFlagsOffset));
- __ And(t1, t1, Operand(Code::KindField::kMask));
- __ srl(t1, t1, Code::KindField::kShift);
- __ Branch(&gotta_call_runtime_no_stack, eq, t1, Operand(Code::BUILTIN));
- // Yes, install the full code.
- __ Addu(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ sw(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
- __ RecordWriteCodeEntryField(closure, entry, t1);
- __ Jump(entry);
-
- __ bind(&gotta_call_runtime);
- __ pop(closure);
- __ pop(new_target);
- __ pop(argument_count);
- __ bind(&gotta_call_runtime_no_stack);
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
diff --git a/src/mips64/builtins-mips64.cc b/src/mips64/builtins-mips64.cc
index a4b144e..95174da 100644
--- a/src/mips64/builtins-mips64.cc
+++ b/src/mips64/builtins-mips64.cc
@@ -1215,154 +1215,6 @@
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- a0 : argument count (preserved for callee)
- // -- a3 : new target (preserved for callee)
- // -- a1 : target function (preserved for callee)
- // -----------------------------------
- // First lookup code, maybe we don't need to compile!
- Label gotta_call_runtime, gotta_call_runtime_no_stack;
- Label maybe_call_runtime;
- Label try_shared;
- Label loop_top, loop_bottom;
-
- Register argument_count = a0;
- Register closure = a1;
- Register new_target = a3;
- __ push(argument_count);
- __ push(new_target);
- __ push(closure);
-
- Register map = a0;
- Register index = a2;
- __ ld(map, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ ld(map, FieldMemOperand(map, SharedFunctionInfo::kOptimizedCodeMapOffset));
- __ ld(index, FieldMemOperand(map, FixedArray::kLengthOffset));
- __ Branch(&gotta_call_runtime, lt, index, Operand(Smi::FromInt(2)));
-
- // Find literals.
- // a3 : native context
- // a2 : length / index
- // a0 : optimized code map
- // stack[0] : new target
- // stack[4] : closure
- Register native_context = a3;
- __ ld(native_context, NativeContextMemOperand());
-
- __ bind(&loop_top);
- Register temp = a1;
- Register array_pointer = a5;
-
- // Does the native context match?
- __ SmiScale(at, index, kPointerSizeLog2);
- __ Daddu(array_pointer, map, Operand(at));
- __ ld(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousContext));
- __ ld(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
- __ Branch(&loop_bottom, ne, temp, Operand(native_context));
- // OSR id set to none?
- __ ld(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousOsrAstId));
- const int bailout_id = BailoutId::None().ToInt();
- __ Branch(&loop_bottom, ne, temp, Operand(Smi::FromInt(bailout_id)));
- // Literals available?
- __ ld(temp, FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousLiterals));
- __ ld(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
- __ JumpIfSmi(temp, &gotta_call_runtime);
-
- // Save the literals in the closure.
- __ ld(a4, MemOperand(sp, 0));
- __ sd(temp, FieldMemOperand(a4, JSFunction::kLiteralsOffset));
- __ push(index);
- __ RecordWriteField(a4, JSFunction::kLiteralsOffset, temp, index,
- kRAHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- __ pop(index);
-
- // Code available?
- Register entry = a4;
- __ ld(entry,
- FieldMemOperand(array_pointer,
- SharedFunctionInfo::kOffsetToPreviousCachedCode));
- __ ld(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &maybe_call_runtime);
-
- // Found literals and code. Get them into the closure and return.
- __ pop(closure);
- // Store code entry in the closure.
- __ Daddu(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
-
- Label install_optimized_code_and_tailcall;
- __ bind(&install_optimized_code_and_tailcall);
- __ sd(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
- __ RecordWriteCodeEntryField(closure, entry, a5);
-
- // Link the closure into the optimized function list.
- // a4 : code entry
- // a3 : native context
- // a1 : closure
- __ ld(a5,
- ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
- __ sd(a5, FieldMemOperand(closure, JSFunction::kNextFunctionLinkOffset));
- __ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, a5, a0,
- kRAHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- const int function_list_offset =
- Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
- __ sd(closure,
- ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
- // Save closure before the write barrier.
- __ mov(a5, closure);
- __ RecordWriteContextSlot(native_context, function_list_offset, closure, a0,
- kRAHasNotBeenSaved, kDontSaveFPRegs);
- __ mov(closure, a5);
- __ pop(new_target);
- __ pop(argument_count);
- __ Jump(entry);
-
- __ bind(&loop_bottom);
- __ Dsubu(index, index,
- Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
- __ Branch(&loop_top, gt, index, Operand(Smi::FromInt(1)));
-
- // We found neither literals nor code.
- __ jmp(&gotta_call_runtime);
-
- __ bind(&maybe_call_runtime);
- __ pop(closure);
-
- // Last possibility. Check the context free optimized code map entry.
- __ ld(entry, FieldMemOperand(map, FixedArray::kHeaderSize +
- SharedFunctionInfo::kSharedCodeIndex));
- __ ld(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &try_shared);
-
- // Store code entry in the closure.
- __ Daddu(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ jmp(&install_optimized_code_and_tailcall);
-
- __ bind(&try_shared);
- __ pop(new_target);
- __ pop(argument_count);
- // Is the full code valid?
- __ ld(entry, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ ld(entry, FieldMemOperand(entry, SharedFunctionInfo::kCodeOffset));
- __ ld(a5, FieldMemOperand(entry, Code::kFlagsOffset));
- __ And(a5, a5, Operand(Code::KindField::kMask));
- __ dsrl(a5, a5, Code::KindField::kShift);
- __ Branch(&gotta_call_runtime_no_stack, eq, a5, Operand(Code::BUILTIN));
- // Yes, install the full code.
- __ Daddu(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ sd(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
- __ RecordWriteCodeEntryField(closure, entry, a5);
- __ Jump(entry);
-
- __ bind(&gotta_call_runtime);
- __ pop(closure);
- __ pop(new_target);
- __ pop(argument_count);
- __ bind(&gotta_call_runtime_no_stack);
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
@@ -1372,6 +1224,7 @@
Runtime::kCompileOptimized_NotConcurrent);
}
+
void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
}
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 639d739..5d138b8 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -5746,6 +5746,7 @@
set_compiler_hints(hints);
}
+
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, needs_home_object,
kNeedsHomeObject)
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
diff --git a/src/objects.h b/src/objects.h
index c7fc768..e3cb08b 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -6688,18 +6688,6 @@
static const int kNotFound = -1;
- // Helpers for assembly code that does a backwards walk of the optimized code
- // map.
- static const int kOffsetToPreviousContext =
- FixedArray::kHeaderSize + kPointerSize * (kContextOffset - kEntryLength);
- static const int kOffsetToPreviousCachedCode =
- FixedArray::kHeaderSize +
- kPointerSize * (kCachedCodeOffset - kEntryLength);
- static const int kOffsetToPreviousLiterals =
- FixedArray::kHeaderSize + kPointerSize * (kLiteralsOffset - kEntryLength);
- static const int kOffsetToPreviousOsrAstId =
- FixedArray::kHeaderSize + kPointerSize * (kOsrAstIdOffset - kEntryLength);
-
// [scope_info]: Scope info.
DECL_ACCESSORS(scope_info, ScopeInfo)
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 38b4440..dbd1328 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -904,134 +904,6 @@
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : argument count (preserved for callee)
- // -- rdx : new target (preserved for callee)
- // -- rdi : target function (preserved for callee)
- // -----------------------------------
- // First lookup code, maybe we don't need to compile!
- Label gotta_call_runtime;
- Label maybe_call_runtime;
- Label try_shared;
- Label loop_top, loop_bottom;
-
- Register closure = rdi;
- Register map = r8;
- Register index = r9;
- __ movp(map, FieldOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ movp(map, FieldOperand(map, SharedFunctionInfo::kOptimizedCodeMapOffset));
- __ SmiToInteger32(index, FieldOperand(map, FixedArray::kLengthOffset));
- __ cmpl(index, Immediate(2));
- __ j(less, &gotta_call_runtime);
-
- // Find literals.
- // r14 : native context
- // r9 : length / index
- // r8 : optimized code map
- // rdx : new target
- // rdi : closure
- Register native_context = r14;
- __ movp(native_context, NativeContextOperand());
-
- __ bind(&loop_top);
- // Native context match?
- Register temp = r11;
- __ movp(temp, FieldOperand(map, index, times_pointer_size,
- SharedFunctionInfo::kOffsetToPreviousContext));
- __ movp(temp, FieldOperand(temp, WeakCell::kValueOffset));
- __ cmpp(temp, native_context);
- __ j(not_equal, &loop_bottom);
- // OSR id set to none?
- __ movp(temp, FieldOperand(map, index, times_pointer_size,
- SharedFunctionInfo::kOffsetToPreviousOsrAstId));
- __ SmiToInteger32(temp, temp);
- const int bailout_id = BailoutId::None().ToInt();
- __ cmpl(temp, Immediate(bailout_id));
- __ j(not_equal, &loop_bottom);
- // Literals available?
- __ movp(temp, FieldOperand(map, index, times_pointer_size,
- SharedFunctionInfo::kOffsetToPreviousLiterals));
- __ movp(temp, FieldOperand(temp, WeakCell::kValueOffset));
- __ JumpIfSmi(temp, &gotta_call_runtime);
-
- // Save the literals in the closure.
- __ movp(FieldOperand(closure, JSFunction::kLiteralsOffset), temp);
- __ movp(r15, index);
- __ RecordWriteField(closure, JSFunction::kLiteralsOffset, temp, r15,
- kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
-
- // Code available?
- Register entry = rcx;
- __ movp(entry, FieldOperand(map, index, times_pointer_size,
- SharedFunctionInfo::kOffsetToPreviousCachedCode));
- __ movp(entry, FieldOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &maybe_call_runtime);
-
- // Found literals and code. Get them into the closure and return.
- __ leap(entry, FieldOperand(entry, Code::kHeaderSize));
-
- Label install_optimized_code_and_tailcall;
- __ bind(&install_optimized_code_and_tailcall);
- __ movp(FieldOperand(closure, JSFunction::kCodeEntryOffset), entry);
- __ RecordWriteCodeEntryField(closure, entry, r15);
-
- // Link the closure into the optimized function list.
- // rcx : code entry (entry)
- // r14 : native context
- // rdx : new target
- // rdi : closure
- __ movp(rbx,
- ContextOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
- __ movp(FieldOperand(closure, JSFunction::kNextFunctionLinkOffset), rbx);
- __ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, rbx, r15,
- kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
- const int function_list_offset =
- Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
- __ movp(ContextOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST),
- closure);
- // Save closure before the write barrier.
- __ movp(rbx, closure);
- __ RecordWriteContextSlot(native_context, function_list_offset, closure, r15,
- kDontSaveFPRegs);
- __ movp(closure, rbx);
- __ jmp(entry);
-
- __ bind(&loop_bottom);
- __ subl(index, Immediate(SharedFunctionInfo::kEntryLength));
- __ cmpl(index, Immediate(1));
- __ j(greater, &loop_top);
-
- // We found neither literals nor code.
- __ jmp(&gotta_call_runtime);
-
- __ bind(&maybe_call_runtime);
-
- // Last possibility. Check the context free optimized code map entry.
- __ movp(entry, FieldOperand(map, FixedArray::kHeaderSize +
- SharedFunctionInfo::kSharedCodeIndex));
- __ movp(entry, FieldOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &try_shared);
-
- // Store code entry in the closure.
- __ leap(entry, FieldOperand(entry, Code::kHeaderSize));
- __ jmp(&install_optimized_code_and_tailcall);
-
- __ bind(&try_shared);
- // Is the full code valid?
- __ movp(entry, FieldOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- __ movp(entry, FieldOperand(entry, SharedFunctionInfo::kCodeOffset));
- __ movl(rbx, FieldOperand(entry, Code::kFlagsOffset));
- __ andl(rbx, Immediate(Code::KindField::kMask));
- __ shrl(rbx, Immediate(Code::KindField::kShift));
- __ cmpl(rbx, Immediate(Code::BUILTIN));
- __ j(equal, &gotta_call_runtime);
- // Yes, install the full code.
- __ leap(entry, FieldOperand(entry, Code::kHeaderSize));
- __ movp(FieldOperand(closure, JSFunction::kCodeEntryOffset), entry);
- __ RecordWriteCodeEntryField(closure, entry, r15);
- __ jmp(entry);
-
- __ bind(&gotta_call_runtime);
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index dbd23e4a..5de6598 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -489,7 +489,7 @@
// easier.
DCHECK(js_function.is(rdi));
DCHECK(code_entry.is(rcx));
- DCHECK(scratch.is(r15));
+ DCHECK(scratch.is(rax));
// Since a code entry (value) is always in old space, we don't need to update
// remembered set. If incremental marking is off, there is nothing for us to
@@ -537,13 +537,13 @@
DCHECK(arg_reg_2.is(rdx) && arg_reg_3.is(r8));
movp(arg_reg_1, js_function); // rcx gets rdi.
- movp(arg_reg_2, dst); // rdx gets r15.
+ movp(arg_reg_2, dst); // rdx gets rax.
} else {
// AMD64 calling convention.
DCHECK(arg_reg_1.is(rdi) && arg_reg_2.is(rsi) && arg_reg_3.is(rdx));
// rdi is already loaded with js_function.
- movp(arg_reg_2, dst); // rsi gets r15.
+ movp(arg_reg_2, dst); // rsi gets rax.
}
Move(arg_reg_3, ExternalReference::isolate_address(isolate()));
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 0b6a14a..165bb3e 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -528,9 +528,6 @@
# code.
'test-api/TurboAsmDisablesNeuter': [FAIL],
- # TODO(mvstanton,4900): CHECK(!g_function->is_compiled());
- 'test-heap/TestUseOfIncrementalBarrierOnCompileLazy': [FAIL],
-
# TODO(rmcilroy,4837): We don't set a LoadContextSlot for a function as
# immutable in the BytecodeGraphBuilder, therefore no inlining happens.
'test-run-inlining/InlineLoopGuardedTwice': [FAIL],
diff --git a/test/cctest/heap/test-heap.cc b/test/cctest/heap/test-heap.cc
index d09d07d..1ba0f50 100644
--- a/test/cctest/heap/test-heap.cc
+++ b/test/cctest/heap/test-heap.cc
@@ -1546,7 +1546,10 @@
Handle<Object> g_value =
Object::GetProperty(isolate->global_object(), g_name).ToHandleChecked();
Handle<JSFunction> g_function = Handle<JSFunction>::cast(g_value);
- CHECK(!g_function->is_compiled());
+ // TODO(mvstanton): change to check that g is *not* compiled when optimized
+ // cache
+ // map lookup moves to the compile lazy builtin.
+ CHECK(g_function->is_compiled());
SimulateIncrementalMarking(heap);
CompileRun("%OptimizeFunctionOnNextCall(f); f();");
diff --git a/test/cctest/test-compiler.cc b/test/cctest/test-compiler.cc
index 18f0009..32d720e 100644
--- a/test/cctest/test-compiler.cc
+++ b/test/cctest/test-compiler.cc
@@ -364,7 +364,9 @@
CHECK(!f->shared()->feedback_vector()->is_empty());
}
-// Test that optimized code for different closures is actually shared.
+
+// Test that optimized code for different closures is actually shared
+// immediately by the FastNewClosureStub when run in the same context.
TEST(OptimizedCodeSharing1) {
FLAG_stress_compaction = false;
FLAG_allow_natives_syntax = true;
@@ -383,8 +385,8 @@
"%DebugPrint(closure0());"
"%OptimizeFunctionOnNextCall(closure0);"
"%DebugPrint(closure0());"
- "var closure1 = MakeClosure(); closure1();"
- "var closure2 = MakeClosure(); closure2();");
+ "var closure1 = MakeClosure();"
+ "var closure2 = MakeClosure();");
Handle<JSFunction> fun1 = Handle<JSFunction>::cast(
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
env->Global()
@@ -401,7 +403,9 @@
}
}
-// Test that optimized code for different closures is actually shared.
+
+// Test that optimized code for different closures is actually shared
+// immediately by the FastNewClosureStub when run different contexts.
TEST(OptimizedCodeSharing2) {
if (FLAG_stress_compaction) return;
FLAG_allow_natives_syntax = true;
@@ -452,8 +456,8 @@
"%DebugPrint(closure0());"
"%OptimizeFunctionOnNextCall(closure0);"
"%DebugPrint(closure0());"
- "var closure1 = MakeClosure(); closure1();"
- "var closure2 = MakeClosure(); closure2();");
+ "var closure1 = MakeClosure();"
+ "var closure2 = MakeClosure();");
Handle<JSFunction> fun1 = Handle<JSFunction>::cast(
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
env->Global()
@@ -471,7 +475,9 @@
}
}
-// Test that optimized code for different closures is actually shared.
+
+// Test that optimized code for different closures is actually shared
+// immediately by the FastNewClosureStub without context-dependent entries.
TEST(OptimizedCodeSharing3) {
if (FLAG_stress_compaction) return;
FLAG_allow_natives_syntax = true;
@@ -525,8 +531,8 @@
"%DebugPrint(closure0());"
"%OptimizeFunctionOnNextCall(closure0);"
"%DebugPrint(closure0());"
- "var closure1 = MakeClosure(); closure1();"
- "var closure2 = MakeClosure(); closure2();");
+ "var closure1 = MakeClosure();"
+ "var closure2 = MakeClosure();");
Handle<JSFunction> fun1 = Handle<JSFunction>::cast(
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
env->Global()