Commit 1af12c3c authored by Jaideep Bajwa's avatar Jaideep Bajwa Committed by Commit Bot

PPC/s390: [builtins] Introduce ConstructProxy builtin based on CSA

Port fe046627
Port d594a6d9
Port 53553f5d

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

Change-Id: I2c160f8e3a1c3a809de6a6631864104ed95900d7
Reviewed-on: https://chromium-review.googlesource.com/587610Reviewed-by: 's avatarJunliang Yan <jyan@ca.ibm.com>
Commit-Queue: Jaideep Bajwa <bjaideep@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#46914}
parent 92732265
......@@ -714,37 +714,15 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
// -- r3 : the value to pass to the generator
// -- r4 : the JSGeneratorObject to resume
// -- r5 : the resume mode (tagged)
// -- r6 : the SuspendFlags of the earlier suspend call (tagged)
// -- lr : return address
// -----------------------------------
__ SmiUntag(r6);
__ AssertGeneratorObject(r4, r6);
__ AssertGeneratorObject(r4);
// Store input value into generator object.
Label async_await, done_store_input;
__ andi(r6, r6,
Operand(static_cast<int>(SuspendFlags::kAsyncGeneratorAwait)));
__ cmpi(r6, Operand(static_cast<int>(SuspendFlags::kAsyncGeneratorAwait)));
__ beq(&async_await);
__ StoreP(r3, FieldMemOperand(r4, JSGeneratorObject::kInputOrDebugPosOffset),
r0);
__ RecordWriteField(r4, JSGeneratorObject::kInputOrDebugPosOffset, r3, r6,
kLRHasNotBeenSaved, kDontSaveFPRegs);
__ b(&done_store_input);
__ bind(&async_await);
__ StoreP(
r3,
FieldMemOperand(r4, JSAsyncGeneratorObject::kAwaitInputOrDebugPosOffset),
r0);
__ RecordWriteField(r4, JSAsyncGeneratorObject::kAwaitInputOrDebugPosOffset,
r3, r6, kLRHasNotBeenSaved, kDontSaveFPRegs);
__ b(&done_store_input);
__ bind(&done_store_input);
// `r6` no longer holds SuspendFlags
// Store resume mode into generator object.
__ StoreP(r5, FieldMemOperand(r4, JSGeneratorObject::kResumeModeOffset), r0);
......@@ -2604,24 +2582,6 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
__ JumpToJSEntry(ip);
}
// static
void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : the number of arguments (not including the receiver)
// -- r4 : the constructor to call (checked to be a JSProxy)
// -- r6 : the new target (either the same as the constructor or
// the JSFunction on which new was invoked initially)
// -----------------------------------
// Call into the Runtime for Proxy [[Construct]].
__ Push(r4, r6);
// Include the pushed new_target, constructor and the receiver.
__ addi(r3, r3, Operand(3));
// Tail-call to the runtime.
__ JumpToExternalReference(
ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
}
// static
void Builtins::Generate_Construct(MacroAssembler* masm) {
// ----------- S t a t e -------------
......@@ -2632,7 +2592,7 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// -----------------------------------
// Check if target is a Smi.
Label non_constructor;
Label non_constructor, non_proxy;
__ JumpIfSmi(r4, &non_constructor);
// Dispatch based on instance type.
......@@ -2653,10 +2613,12 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// Only dispatch to proxies after checking whether they are constructors.
__ cmpi(r8, Operand(JS_PROXY_TYPE));
__ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
eq);
__ bne(&non_proxy);
__ TailCallBuiltin(Builtins::kConstructProxy);
// Called Construct on an exotic Object with a [[Construct]] internal method.
__ bind(&non_proxy);
{
// Overwrite the original receiver with the (original) target.
__ ShiftLeftImm(r8, r3, Operand(kPointerSizeLog2));
......
......@@ -702,35 +702,15 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
// -- r2 : the value to pass to the generator
// -- r3 : the JSGeneratorObject to resume
// -- r4 : the resume mode (tagged)
// -- r5 : the SuspendFlags of the earlier suspend call (tagged)
// -- lr : return address
// -----------------------------------
__ SmiUntag(r5);
__ AssertGeneratorObject(r3, r5);
__ AssertGeneratorObject(r3);
// Store input value into generator object.
Label async_await, done_store_input;
__ tmll(r5, Operand(static_cast<int>(SuspendFlags::kAsyncGeneratorAwait)));
__ b(Condition(1), &async_await);
__ StoreP(r2, FieldMemOperand(r3, JSGeneratorObject::kInputOrDebugPosOffset),
r0);
__ RecordWriteField(r3, JSGeneratorObject::kInputOrDebugPosOffset, r2, r5,
kLRHasNotBeenSaved, kDontSaveFPRegs);
__ b(&done_store_input);
__ bind(&async_await);
__ StoreP(
r2,
FieldMemOperand(r3, JSAsyncGeneratorObject::kAwaitInputOrDebugPosOffset),
r0);
__ RecordWriteField(r3, JSAsyncGeneratorObject::kAwaitInputOrDebugPosOffset,
r2, r5, kLRHasNotBeenSaved, kDontSaveFPRegs);
__ b(&done_store_input);
__ bind(&done_store_input);
// `r5` no longer holds SuspendFlags
// Store resume mode into generator object.
__ StoreP(r4, FieldMemOperand(r3, JSGeneratorObject::kResumeModeOffset));
......@@ -2604,24 +2584,6 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
__ JumpToJSEntry(ip);
}
// static
void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : the number of arguments (not including the receiver)
// -- r3 : the constructor to call (checked to be a JSProxy)
// -- r5 : the new target (either the same as the constructor or
// the JSFunction on which new was invoked initially)
// -----------------------------------
// Call into the Runtime for Proxy [[Construct]].
__ Push(r3, r5);
// Include the pushed new_target, constructor and the receiver.
__ AddP(r2, r2, Operand(3));
// Tail-call to the runtime.
__ JumpToExternalReference(
ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
}
// static
void Builtins::Generate_Construct(MacroAssembler* masm) {
// ----------- S t a t e -------------
......@@ -2632,7 +2594,7 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// -----------------------------------
// Check if target is a Smi.
Label non_constructor;
Label non_constructor, non_proxy;
__ JumpIfSmi(r3, &non_constructor);
// Dispatch based on instance type.
......@@ -2653,10 +2615,12 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// Only dispatch to proxies after checking whether they are constructors.
__ CmpP(r7, Operand(JS_PROXY_TYPE));
__ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
eq);
__ bne(&non_proxy);
__ TailCallBuiltin(Builtins::kConstructProxy);
// Called Construct on an exotic Object with a [[Construct]] internal method.
__ bind(&non_proxy);
{
// Overwrite the original receiver with the (original) target.
__ ShiftLeftP(r7, r2, Operand(kPointerSizeLog2));
......
......@@ -63,7 +63,7 @@ class PPCOperandConverter final : public InstructionOperandConverter {
case Constant::kFloat32:
return Operand::EmbeddedNumber(constant.ToFloat32());
case Constant::kFloat64:
return Operand::EmbeddedNumber(constant.ToFloat64());
return Operand::EmbeddedNumber(constant.ToFloat64().value());
case Constant::kInt64:
#if V8_TARGET_ARCH_PPC64
return Operand(constant.ToInt64());
......@@ -2404,7 +2404,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
__ mov(dst, Operand::EmbeddedNumber(src.ToFloat32()));
break;
case Constant::kFloat64:
__ mov(dst, Operand::EmbeddedNumber(src.ToFloat64()));
__ mov(dst, Operand::EmbeddedNumber(src.ToFloat64().value()));
break;
case Constant::kExternalReference:
__ mov(dst, Operand(src.ToExternalReference()));
......@@ -2445,7 +2445,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
value = Double(static_cast<double>(src.ToFloat32()));
}
} else {
value = src.ToFloat64();
value = Double(src.ToFloat64());
}
#else
value = Double((src.type() == Constant::kFloat32)
......
......@@ -58,7 +58,7 @@ class S390OperandConverter final : public InstructionOperandConverter {
case Constant::kFloat32:
return Operand::EmbeddedNumber(constant.ToFloat32());
case Constant::kFloat64:
return Operand::EmbeddedNumber(constant.ToFloat64());
return Operand::EmbeddedNumber(constant.ToFloat64().value());
case Constant::kInt64:
#if V8_TARGET_ARCH_S390X
return Operand(constant.ToInt64());
......@@ -2775,7 +2775,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
__ mov(dst, Operand::EmbeddedNumber(src.ToFloat32()));
break;
case Constant::kFloat64:
__ mov(dst, Operand::EmbeddedNumber(src.ToFloat64()));
__ mov(dst, Operand::EmbeddedNumber(src.ToFloat64().value()));
break;
case Constant::kExternalReference:
__ mov(dst, Operand(src.ToExternalReference()));
......
......@@ -1402,11 +1402,6 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
}
}
void FullCodeGenerator::VisitSuspend(Suspend* expr) {
// Resumable functions are not supported.
UNREACHABLE();
}
void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
OperandStackDepthIncrement(2);
__ Push(reg1, reg2);
......
......@@ -1367,11 +1367,6 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
}
}
void FullCodeGenerator::VisitSuspend(Suspend* expr) {
// Resumable functions are not supported.
UNREACHABLE();
}
void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
OperandStackDepthIncrement(2);
__ Push(reg1, reg2);
......
......@@ -426,8 +426,7 @@ void ResumeGeneratorDescriptor::InitializePlatformSpecific(
Register registers[] = {
r3, // the value to pass to the generator
r4, // the JSGeneratorObject to resume
r5, // the resume mode (tagged)
r6 // SuspendFlags (tagged)
r5 // the resume mode (tagged)
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -12,6 +12,7 @@
#include "src/bootstrapper.h"
#include "src/codegen.h"
#include "src/debug/debug.h"
#include "src/external-reference-table.h"
#include "src/register-configuration.h"
#include "src/runtime/runtime.h"
......@@ -1909,6 +1910,14 @@ void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) {
Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
}
void MacroAssembler::TailCallBuiltin(Builtins::Name name) {
DCHECK(ExternalReferenceTable::HasBuiltin(name));
mov(ip, Operand(ExternalReference(Builtins::kConstructProxy, isolate())));
LoadP(ip, MemOperand(ip));
addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
Jump(ip);
}
bool TurboAssembler::AllowThisStubCall(CodeStub* stub) {
return has_frame_ || !stub->SometimesSetsUpAFrame();
}
......@@ -2332,8 +2341,7 @@ void MacroAssembler::AssertBoundFunction(Register object) {
}
}
void MacroAssembler::AssertGeneratorObject(Register object, Register flags) {
// `flags` should be an untagged integer. See `SuspendFlags` in src/globals.h
void MacroAssembler::AssertGeneratorObject(Register object) {
if (!emit_debug_code()) return;
TestIfSmi(object, r0);
Check(ne, kOperandIsASmiAndNotAGeneratorObject, cr0);
......@@ -2343,17 +2351,14 @@ void MacroAssembler::AssertGeneratorObject(Register object, Register flags) {
push(object);
LoadP(map, FieldMemOperand(object, HeapObject::kMapOffset));
Label async, do_check;
TestBitMask(flags, static_cast<int>(SuspendFlags::kGeneratorTypeMask), r0);
bne(&async, cr0);
// Check if JSGeneratorObject
CompareInstanceType(map, object, JS_GENERATOR_OBJECT_TYPE);
b(&do_check);
Label do_check;
Register instance_type = object;
CompareInstanceType(map, instance_type, JS_GENERATOR_OBJECT_TYPE);
beq(&do_check);
bind(&async);
// Check if JSAsyncGeneratorObject
CompareInstanceType(map, object, JS_ASYNC_GENERATOR_OBJECT_TYPE);
// Check if JSAsyncGeneratorObject (See MacroAssembler::CompareInstanceType)
cmpi(instance_type, Operand(JS_ASYNC_GENERATOR_OBJECT_TYPE));
bind(&do_check);
// Restore generator object to register and perform assertion
......
......@@ -1077,6 +1077,9 @@ class MacroAssembler : public TurboAssembler {
void CallStub(CodeStub* stub, Condition cond = al);
void TailCallStub(CodeStub* stub, Condition cond = al);
// Tail call a code builtin (jump).
void TailCallBuiltin(Builtins::Name name);
// Call a runtime routine.
void CallRuntime(const Runtime::Function* f, int num_arguments,
SaveFPRegsMode save_doubles = kDontSaveFPRegs);
......@@ -1299,9 +1302,9 @@ class MacroAssembler : public TurboAssembler {
// enabled via --debug-code.
void AssertBoundFunction(Register object);
// Abort execution if argument is not a JSGeneratorObject,
// Abort execution if argument is not a JSGeneratorObject (or subclass),
// enabled via --debug-code.
void AssertGeneratorObject(Register object, Register suspend_flags);
void AssertGeneratorObject(Register object);
// Abort execution if argument is not undefined or an AllocationSite, enabled
// via --debug-code.
......
......@@ -409,8 +409,7 @@ void ResumeGeneratorDescriptor::InitializePlatformSpecific(
Register registers[] = {
r2, // the value to pass to the generator
r3, // the JSGeneratorObject to resume
r4, // the resume mode (tagged)
r5 // SuspendFlags (tagged)
r4 // the resume mode (tagged)
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -12,6 +12,7 @@
#include "src/bootstrapper.h"
#include "src/codegen.h"
#include "src/debug/debug.h"
#include "src/external-reference-table.h"
#include "src/register-configuration.h"
#include "src/runtime/runtime.h"
......@@ -1762,6 +1763,14 @@ void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) {
Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
}
void MacroAssembler::TailCallBuiltin(Builtins::Name name) {
DCHECK(ExternalReferenceTable::HasBuiltin(name));
mov(ip, Operand(ExternalReference(Builtins::kConstructProxy, isolate())));
LoadP(ip, MemOperand(ip));
AddP(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
Jump(ip);
}
bool TurboAssembler::AllowThisStubCall(CodeStub* stub) {
return has_frame_ || !stub->SometimesSetsUpAFrame();
}
......@@ -2141,8 +2150,7 @@ void MacroAssembler::AssertBoundFunction(Register object) {
}
}
void MacroAssembler::AssertGeneratorObject(Register object, Register flags) {
// `flags` should be an untagged integer. See `SuspendFlags` in src/globals.h
void MacroAssembler::AssertGeneratorObject(Register object) {
if (!emit_debug_code()) return;
TestIfSmi(object);
Check(ne, kOperandIsASmiAndNotAGeneratorObject, cr0);
......@@ -2152,17 +2160,14 @@ void MacroAssembler::AssertGeneratorObject(Register object, Register flags) {
push(object);
LoadP(map, FieldMemOperand(object, HeapObject::kMapOffset));
Label async, do_check;
tmll(flags, Operand(static_cast<int>(SuspendFlags::kGeneratorTypeMask)));
bne(&async);
// Check if JSGeneratorObject
CompareInstanceType(map, object, JS_GENERATOR_OBJECT_TYPE);
b(&do_check);
Label do_check;
Register instance_type = object;
CompareInstanceType(map, instance_type, JS_GENERATOR_OBJECT_TYPE);
beq(&do_check);
bind(&async);
// Check if JSAsyncGeneratorObject
CompareInstanceType(map, object, JS_ASYNC_GENERATOR_OBJECT_TYPE);
// Check if JSAsyncGeneratorObject (See MacroAssembler::CompareInstanceType)
CmpP(instance_type, Operand(JS_ASYNC_GENERATOR_OBJECT_TYPE));
bind(&do_check);
// Restore generator object to register and perform assertion
......
......@@ -999,6 +999,10 @@ class MacroAssembler : public TurboAssembler {
}
// Call a code stub.
void TailCallStub(CodeStub* stub, Condition cond = al);
// Tail call a code builtin (jump).
void TailCallBuiltin(Builtins::Name name);
void CallStub(CodeStub* stub, Condition cond = al);
void CallRuntime(const Runtime::Function* f, int num_arguments,
SaveFPRegsMode save_doubles = kDontSaveFPRegs);
......@@ -1461,9 +1465,9 @@ class MacroAssembler : public TurboAssembler {
// enabled via --debug-code.
void AssertBoundFunction(Register object);
// Abort execution if argument is not a JSGeneratorObject,
// Abort execution if argument is not a JSGeneratorObject (or subclass),
// enabled via --debug-code.
void AssertGeneratorObject(Register object, Register suspend_flags);
void AssertGeneratorObject(Register object);
// Abort execution if argument is not undefined or an AllocationSite, enabled
// via --debug-code.
......
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