Commit d9daf859 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[csa][builtins] Port DeserializeLazy to CSA.

Bug: v8:5269, v8:7703
Change-Id: I0b766ab4ca55edc05d1849745fd3604be6c726d6
Reviewed-on: https://chromium-review.googlesource.com/1087460
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53607}
parent e5318195
......@@ -1282,78 +1282,6 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
Generate_InterpreterEnterBytecode(masm);
}
// Lazy deserialization design doc: http://goo.gl/dxkYDZ.
void Builtins::Generate_DeserializeLazy(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)
// -----------------------------------
Label deserialize_in_runtime;
Register target = r1; // Must be preserved
Register scratch0 = r2;
Register scratch1 = r4;
CHECK(scratch0 != r0 && scratch0 != r3 && scratch0 != r1);
CHECK(scratch1 != r0 && scratch1 != r3 && scratch1 != r1);
CHECK(scratch0 != scratch1);
// Load the builtin id for lazy deserialization from SharedFunctionInfo.
__ AssertFunction(target);
__ ldr(scratch0,
FieldMemOperand(target, JSFunction::kSharedFunctionInfoOffset));
__ ldr(scratch1,
FieldMemOperand(scratch0, SharedFunctionInfo::kFunctionDataOffset));
__ AssertSmi(scratch1);
// The builtin may already have been deserialized. If that is the case, it is
// stored in the builtins table, and we can copy to correct code object to
// both the shared function info and function without calling into runtime.
//
// Otherwise, we need to call into runtime to deserialize.
{
// Load the code object at builtins_table[builtin_id] into scratch1.
__ SmiUntag(scratch1);
__ Move(scratch0, ExternalReference::builtins_address(masm->isolate()));
__ ldr(scratch1, MemOperand(scratch0, scratch1, LSL, kPointerSizeLog2));
// Check if the loaded code object has already been deserialized. This is
// the case iff it does not equal DeserializeLazy.
__ Move(scratch0, masm->CodeObject());
__ cmp(scratch1, scratch0);
__ b(eq, &deserialize_in_runtime);
}
{
// If we've reached this spot, the target builtin has been deserialized and
// we simply need to copy it over to the target function.
Register target_builtin = scratch1;
__ str(target_builtin, FieldMemOperand(target, JSFunction::kCodeOffset));
__ mov(r9, target_builtin); // Write barrier clobbers r9 below.
__ RecordWriteField(target, JSFunction::kCodeOffset, r9, r5,
kLRHasNotBeenSaved, kDontSaveFPRegs,
OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
// All copying is done. Jump to the deserialized code object.
__ add(target_builtin, target_builtin,
Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(target_builtin);
}
__ bind(&deserialize_in_runtime);
GenerateTailCallToReturnedCode(masm, Runtime::kDeserializeLazy);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : argument count (preserved for callee)
......
......@@ -1383,78 +1383,6 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
Generate_InterpreterEnterBytecode(masm);
}
// Lazy deserialization design doc: http://goo.gl/dxkYDZ.
void Builtins::Generate_DeserializeLazy(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)
// -----------------------------------
Label deserialize_in_runtime;
Register target = x1; // Must be preserved
Register scratch0 = x2;
Register scratch1 = x4;
CHECK(!scratch0.is(x0) && !scratch0.is(x3) && !scratch0.is(x1));
CHECK(!scratch1.is(x0) && !scratch1.is(x3) && !scratch1.is(x1));
CHECK(!scratch0.is(scratch1));
// Load the builtin id for lazy deserialization from SharedFunctionInfo.
__ AssertFunction(target);
__ Ldr(scratch0,
FieldMemOperand(target, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(scratch1,
FieldMemOperand(scratch0, SharedFunctionInfo::kFunctionDataOffset));
__ AssertSmi(scratch1);
// The builtin may already have been deserialized. If that is the case, it is
// stored in the builtins table, and we can copy to correct code object to
// both the shared function info and function without calling into runtime.
//
// Otherwise, we need to call into runtime to deserialize.
{
// Load the code object at builtins_table[builtin_id] into scratch1.
__ SmiUntag(scratch1);
__ Mov(scratch0, ExternalReference::builtins_address(masm->isolate()));
__ Ldr(scratch1, MemOperand(scratch0, scratch1, LSL, kPointerSizeLog2));
// Check if the loaded code object has already been deserialized. This is
// the case iff it does not equal DeserializeLazy.
__ Move(scratch0, masm->CodeObject());
__ Cmp(scratch1, scratch0);
__ B(eq, &deserialize_in_runtime);
}
{
// If we've reached this spot, the target builtin has been deserialized and
// we simply need to copy it over to the target function.
Register target_builtin = scratch1;
__ Str(target_builtin, FieldMemOperand(target, JSFunction::kCodeOffset));
__ Mov(x9, target_builtin); // Write barrier clobbers x9 below.
__ RecordWriteField(target, JSFunction::kCodeOffset, x9, x5,
kLRHasNotBeenSaved, kDontSaveFPRegs,
OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
// All copying is done. Jump to the deserialized code object.
__ Add(target_builtin, target_builtin,
Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(target_builtin);
}
__ bind(&deserialize_in_runtime);
GenerateTailCallToReturnedCode(masm, Runtime::kDeserializeLazy);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- x0 : argument count (preserved for callee)
......
......@@ -122,7 +122,7 @@ namespace internal {
/* Code life-cycle */ \
TFC(CompileLazy, ConstructTrampoline, 1) \
TFC(CompileLazyDeoptimizedCode, ConstructTrampoline, 1) \
ASM(DeserializeLazy) \
TFC(DeserializeLazy, ConstructTrampoline, 1) \
ASM(InstantiateAsmJs) \
ASM(NotifyDeoptimized) \
\
......
......@@ -161,5 +161,43 @@ TF_BUILTIN(CompileLazyDeoptimizedCode, LazyBuiltinsAssembler) {
GenerateTailCallToJSCode(code, function);
}
// Lazy deserialization design doc: http://goo.gl/dxkYDZ.
TF_BUILTIN(DeserializeLazy, LazyBuiltinsAssembler) {
Label deserialize_in_runtime(this, Label::kDeferred);
TNode<JSFunction> function = CAST(Parameter(Descriptor::kFunction));
// Load the builtin id for lazy deserialization from SharedFunctionInfo.
TNode<SharedFunctionInfo> shared =
CAST(LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset));
TNode<Smi> sfi_data =
CAST(LoadObjectField(shared, SharedFunctionInfo::kFunctionDataOffset));
// The builtin may already have been deserialized. If that is the case, it is
// stored in the builtins table, and we can copy to correct code object to
// both the shared function info and function without calling into runtime.
//
// Otherwise, we need to call into runtime to deserialize.
TNode<Code> code = LoadBuiltin(sfi_data);
// Check if the loaded code object has already been deserialized. This is
// the case iff it does not equal DeserializeLazy.
GotoIf(
WordEqual(code, HeapConstant(BUILTIN_CODE(isolate(), DeserializeLazy))),
&deserialize_in_runtime);
// If we've reached this spot, the target builtin has been deserialized and
// we simply need to copy it over to the target function.
StoreObjectField(function, JSFunction::kCodeOffset, code);
// All copying is done. Jump to the deserialized code object.
GenerateTailCallToJSCode(code, function);
BIND(&deserialize_in_runtime);
{ GenerateTailCallToReturnedCode(Runtime::kDeserializeLazy, function); }
}
} // namespace internal
} // namespace v8
......@@ -1340,79 +1340,6 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
Generate_InterpreterEnterBytecode(masm);
}
// Lazy deserialization design doc: http://goo.gl/dxkYDZ.
void Builtins::Generate_DeserializeLazy(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)
// -----------------------------------
Label deserialize_in_runtime;
Register target = edi; // Must be preserved
Register scratch0 = ebx;
Register scratch1 = ecx;
CHECK(scratch0 != eax && scratch0 != edx && scratch0 != edi);
CHECK(scratch1 != eax && scratch1 != edx && scratch1 != edi);
CHECK(scratch0 != scratch1);
// Load the builtin id for lazy deserialization from SharedFunctionInfo.
__ AssertFunction(target);
__ mov(scratch0, FieldOperand(target, JSFunction::kSharedFunctionInfoOffset));
__ mov(scratch1,
FieldOperand(scratch0, SharedFunctionInfo::kFunctionDataOffset));
__ AssertSmi(scratch1);
// The builtin may already have been deserialized. If that is the case, it is
// stored in the builtins table, and we can copy to correct code object to
// both the shared function info and function without calling into runtime.
//
// Otherwise, we need to call into runtime to deserialize.
{
// Load the code object at builtins_table[builtin_id] into scratch1.
__ SmiUntag(scratch1);
__ mov(scratch0,
Immediate(ExternalReference::builtins_address(masm->isolate())));
__ mov(scratch1, Operand(scratch0, scratch1, times_pointer_size, 0));
// Check if the loaded code object has already been deserialized. This is
// the case iff it does not equal DeserializeLazy.
__ Move(scratch0, masm->CodeObject());
__ cmp(scratch1, scratch0);
__ j(equal, &deserialize_in_runtime);
}
{
// If we've reached this spot, the target builtin has been deserialized and
// we simply need to copy it over to the target function.
Register target_builtin = scratch1;
__ mov(FieldOperand(target, JSFunction::kCodeOffset), target_builtin);
__ push(eax); // Write barrier clobbers these below.
__ push(target_builtin);
__ RecordWriteField(target, JSFunction::kCodeOffset, target_builtin, eax,
kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
__ pop(target_builtin);
__ pop(eax);
// All copying is done. Jump to the deserialized code object.
__ lea(target_builtin, FieldOperand(target_builtin, Code::kHeaderSize));
__ jmp(target_builtin);
}
__ bind(&deserialize_in_runtime);
GenerateTailCallToReturnedCode(masm, Runtime::kDeserializeLazy);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : argument count (preserved for callee)
......
......@@ -1280,76 +1280,6 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
Generate_InterpreterEnterBytecode(masm);
}
// Lazy deserialization design doc: http://goo.gl/dxkYDZ.
void Builtins::Generate_DeserializeLazy(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)
// -----------------------------------
Label deserialize_in_runtime;
Register target = a1; // Must be preserved
Register scratch0 = a2;
Register scratch1 = t0;
CHECK(scratch0 != a0 && scratch0 != a3 && scratch0 != a1);
CHECK(scratch1 != a0 && scratch1 != a3 && scratch1 != a1);
CHECK(scratch0 != scratch1);
// Load the builtin id for lazy deserialization from SharedFunctionInfo.
__ AssertFunction(target);
__ lw(scratch0,
FieldMemOperand(target, JSFunction::kSharedFunctionInfoOffset));
__ lw(scratch1,
FieldMemOperand(scratch0, SharedFunctionInfo::kFunctionDataOffset));
__ AssertSmi(scratch1);
// The builtin may already have been deserialized. If that is the case, it is
// stored in the builtins table, and we can copy to correct code object to
// both the shared function info and function without calling into runtime.
//
// Otherwise, we need to call into runtime to deserialize.
{
// Load the code object at builtins_table[builtin_id] into scratch1.
__ SmiUntag(scratch1);
__ li(scratch0, ExternalReference::builtins_address(masm->isolate()));
__ Lsa(scratch1, scratch0, scratch1, kPointerSizeLog2);
__ lw(scratch1, MemOperand(scratch1));
// Check if the loaded code object has already been deserialized. This is
// the case iff it does not equal DeserializeLazy.
__ Move(scratch0, masm->CodeObject());
__ Branch(&deserialize_in_runtime, eq, scratch1, Operand(scratch0));
}
{
// If we've reached this spot, the target builtin has been deserialized and
// we simply need to copy it over to the target function.
Register target_builtin = scratch1;
__ sw(target_builtin, FieldMemOperand(target, JSFunction::kCodeOffset));
__ mov(t3, target_builtin); // Write barrier clobbers t3 below.
__ RecordWriteField(target, JSFunction::kCodeOffset, t3, t1,
kRAHasNotBeenSaved, kDontSaveFPRegs,
OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
// All copying is done. Jump to the deserialized code object.
__ Jump(target_builtin, Code::kHeaderSize - kHeapObjectTag);
}
__ bind(&deserialize_in_runtime);
GenerateTailCallToReturnedCode(masm, Runtime::kDeserializeLazy);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : argument count (preserved for callee)
......
......@@ -1278,78 +1278,6 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
Generate_InterpreterEnterBytecode(masm);
}
// Lazy deserialization design doc: http://goo.gl/dxkYDZ.
void Builtins::Generate_DeserializeLazy(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)
// -----------------------------------
Label deserialize_in_runtime;
Register target = a1; // Must be preserved
Register scratch0 = a2;
Register scratch1 = t0;
CHECK(scratch0 != a0 && scratch0 != a3 && scratch0 != a1);
CHECK(scratch1 != a0 && scratch1 != a3 && scratch1 != a1);
CHECK(scratch0 != scratch1);
// Load the builtin id for lazy deserialization from SharedFunctionInfo.
__ AssertFunction(target);
__ Ld(scratch0,
FieldMemOperand(target, JSFunction::kSharedFunctionInfoOffset));
__ Ld(scratch1,
FieldMemOperand(scratch0, SharedFunctionInfo::kFunctionDataOffset));
__ AssertSmi(scratch1);
// The builtin may already have been deserialized. If that is the case, it is
// stored in the builtins table, and we can copy to correct code object to
// both the shared function info and function without calling into runtime.
//
// Otherwise, we need to call into runtime to deserialize.
{
// Load the code object at builtins_table[builtin_id] into scratch1.
__ SmiUntag(scratch1);
__ li(scratch0, ExternalReference::builtins_address(masm->isolate()));
__ Dlsa(scratch1, scratch0, scratch1, kPointerSizeLog2);
__ Ld(scratch1, MemOperand(scratch1));
// Check if the loaded code object has already been deserialized. This is
// the case iff it does not equal DeserializeLazy.
__ Move(scratch0, masm->CodeObject());
__ Branch(&deserialize_in_runtime, eq, scratch1, Operand(scratch0));
}
{
// If we've reached this spot, the target builtin has been deserialized and
// we simply need to copy it over to the target function.
Register target_builtin = scratch1;
__ Sd(target_builtin, FieldMemOperand(target, JSFunction::kCodeOffset));
__ mov(t3, target_builtin); // Write barrier clobbers t3 below.
__ RecordWriteField(target, JSFunction::kCodeOffset, t3, t1,
kRAHasNotBeenSaved, kDontSaveFPRegs,
OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
// All copying is done. Jump to the deserialized code object.
__ Daddu(target_builtin, target_builtin,
Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(target_builtin);
}
__ bind(&deserialize_in_runtime);
GenerateTailCallToReturnedCode(masm, Runtime::kDeserializeLazy);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : argument count (preserved for callee)
......
......@@ -1311,80 +1311,6 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
Generate_InterpreterEnterBytecode(masm);
}
// Lazy deserialization design doc: http://goo.gl/dxkYDZ.
void Builtins::Generate_DeserializeLazy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : argument count (preserved for callee)
// -- r6 : new target (preserved for callee)
// -- r4 : target function (preserved for callee)
// -----------------------------------
Label deserialize_in_runtime;
Register target = r4; // Must be preserved
Register scratch0 = r5;
Register scratch1 = r7;
CHECK(scratch0 != r3 && scratch0 != r6 && scratch0 != r4);
CHECK(scratch1 != r3 && scratch1 != r6 && scratch1 != r4);
CHECK(scratch0 != scratch1);
// Load the builtin id for lazy deserialization from SharedFunctionInfo.
__ AssertFunction(target);
__ LoadP(scratch0,
FieldMemOperand(target, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(scratch1,
FieldMemOperand(scratch0, SharedFunctionInfo::kFunctionDataOffset));
__ AssertSmi(scratch1);
// The builtin may already have been deserialized. If that is the case, it is
// stored in the builtins table, and we can copy to correct code object to
// both the shared function info and function without calling into runtime.
//
// Otherwise, we need to call into runtime to deserialize.
{
// Load the code object at builtins_table[builtin_id] into scratch1.
__ SmiUntag(scratch1);
__ Move(scratch0, ExternalReference::builtins_address(masm->isolate()));
__ ShiftLeftImm(scratch1, scratch1, Operand(kPointerSizeLog2));
__ LoadPX(scratch1, MemOperand(scratch0, scratch1));
// Check if the loaded code object has already been deserialized. This is
// the case iff it does not equal DeserializeLazy.
__ Move(scratch0, masm->CodeObject());
__ cmp(scratch1, scratch0);
__ beq(&deserialize_in_runtime);
}
{
// If we've reached this spot, the target builtin has been deserialized and
// we simply need to copy it over to the target function.
Register target_builtin = scratch1;
__ StoreP(target_builtin, FieldMemOperand(target, JSFunction::kCodeOffset),
r0);
__ mr(r9, target_builtin); // Write barrier clobbers r9 below.
__ RecordWriteField(target, JSFunction::kCodeOffset, r9, r8,
kLRHasNotBeenSaved, kDontSaveFPRegs,
OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
// All copying is done. Jump to the deserialized code object.
__ addi(target_builtin, target_builtin,
Operand(Code::kHeaderSize - kHeapObjectTag));
__ mr(ip, target_builtin);
__ Jump(ip);
}
__ bind(&deserialize_in_runtime);
GenerateTailCallToReturnedCode(masm, Runtime::kDeserializeLazy);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : argument count (preserved for callee)
......
......@@ -1323,79 +1323,6 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
Generate_InterpreterEnterBytecode(masm);
}
// Lazy deserialization design doc: http://goo.gl/dxkYDZ.
void Builtins::Generate_DeserializeLazy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : argument count (preserved for callee)
// -- r5 : new target (preserved for callee)
// -- r3 : target function (preserved for callee)
// -----------------------------------
Label deserialize_in_runtime;
Register target = r3; // Must be preserved
Register scratch0 = r4;
Register scratch1 = r6;
CHECK(scratch0 != r2 && scratch0 != r5 && scratch0 != r3);
CHECK(scratch1 != r2 && scratch1 != r5 && scratch1 != r3);
CHECK(scratch0 != scratch1);
// Load the builtin id for lazy deserialization from SharedFunctionInfo.
__ AssertFunction(target);
__ LoadP(scratch0,
FieldMemOperand(target, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(scratch1,
FieldMemOperand(scratch0, SharedFunctionInfo::kFunctionDataOffset));
__ AssertSmi(scratch1);
// The builtin may already have been deserialized. If that is the case, it is
// stored in the builtins table, and we can copy to correct code object to
// both the shared function info and function without calling into runtime.
//
// Otherwise, we need to call into runtime to deserialize.
{
// Load the code object at builtins_table[builtin_id] into scratch1.
__ SmiUntag(scratch1);
__ Move(scratch0, ExternalReference::builtins_address(masm->isolate()));
__ ShiftLeftP(scratch1, scratch1, Operand(kPointerSizeLog2));
__ LoadP(scratch1, MemOperand(scratch0, scratch1));
// Check if the loaded code object has already been deserialized. This is
// the case iff it does not equal DeserializeLazy.
__ Move(scratch0, masm->CodeObject());
__ CmpP(scratch1, scratch0);
__ beq(&deserialize_in_runtime);
}
{
// If we've reached this spot, the target builtin has been deserialized and
// we simply need to copy it over to the target function.
Register target_builtin = scratch1;
__ StoreP(target_builtin, FieldMemOperand(target, JSFunction::kCodeOffset));
__ LoadRR(r8, target_builtin); // Write barrier clobbers r9 below.
__ RecordWriteField(target, JSFunction::kCodeOffset, r8, r7,
kLRHasNotBeenSaved, kDontSaveFPRegs,
OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
// All copying is done. Jump to the deserialized code object.
__ AddP(target_builtin, target_builtin,
Operand(Code::kHeaderSize - kHeapObjectTag));
__ LoadRR(ip, target_builtin);
__ Jump(ip);
}
__ bind(&deserialize_in_runtime);
GenerateTailCallToReturnedCode(masm, Runtime::kDeserializeLazy);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : argument count (preserved for callee)
......
......@@ -1310,76 +1310,6 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
Generate_InterpreterEnterBytecode(masm);
}
// Lazy deserialization design doc: http://goo.gl/dxkYDZ.
void Builtins::Generate_DeserializeLazy(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)
// -----------------------------------
Label deserialize_in_runtime;
Register target = rdi; // Must be preserved
Register scratch0 = rbx;
Register scratch1 = r12;
CHECK(scratch0 != rax && scratch0 != rdx && scratch0 != rdi);
CHECK(scratch1 != rax && scratch1 != rdx && scratch1 != rdi);
CHECK(scratch0 != scratch1);
// Load the builtin id for lazy deserialization from SharedFunctionInfo.
__ AssertFunction(target);
__ movp(scratch0,
FieldOperand(target, JSFunction::kSharedFunctionInfoOffset));
__ movp(scratch1,
FieldOperand(scratch0, SharedFunctionInfo::kFunctionDataOffset));
__ AssertSmi(scratch1);
// The builtin may already have been deserialized. If that is the case, it is
// stored in the builtins table, and we can copy to correct code object to
// both the shared function info and function without calling into runtime.
//
// Otherwise, we need to call into runtime to deserialize.
{
// Load the code object at builtins_table[builtin_id] into scratch1.
__ SmiUntag(scratch1, scratch1);
__ Move(scratch0, ExternalReference::builtins_address(masm->isolate()));
__ movp(scratch1, Operand(scratch0, scratch1, times_pointer_size, 0));
// Check if the loaded code object has already been deserialized. This is
// the case iff it does not equal DeserializeLazy.
__ Move(scratch0, masm->CodeObject());
__ cmpp(scratch1, scratch0);
__ j(equal, &deserialize_in_runtime);
}
{
// If we've reached this spot, the target builtin has been deserialized and
// we simply need to copy it over to the target function.
Register target_builtin = scratch1;
__ movp(FieldOperand(target, JSFunction::kCodeOffset), target_builtin);
__ movp(r14, target_builtin); // Write barrier clobbers r14 below.
__ RecordWriteField(target, JSFunction::kCodeOffset, r14, r15,
kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
// All copying is done. Jump to the deserialized code object.
__ leap(target_builtin, FieldOperand(target_builtin, Code::kHeaderSize));
__ jmp(target_builtin);
}
__ bind(&deserialize_in_runtime);
GenerateTailCallToReturnedCode(masm, Runtime::kDeserializeLazy);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : argument count (preserved for callee)
......
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