Commit 28371a57 authored by jameslahm's avatar jameslahm Committed by V8 LUCI CQ

[destructuring assignment] add CopyDataPropertiesWithExcludedProperties intrinsic

- add CopyDataPropertiesWithExcludedProperties intrinsic
- add CopyDataPropertiesWithExcludedProperties_Baseline intrinsic

Bug: v8:11614
Change-Id: Ie6a3db4c9edda40ecf84b8d1107e70fd7ff0d5fb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3470349Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79342}
parent a523f5ca
......@@ -83,6 +83,11 @@ MemOperand BaselineAssembler::RegisterFrameOperand(
interpreter::Register interpreter_register) {
return MemOperand(fp, interpreter_register.ToOperand() * kSystemPointerSize);
}
void BaselineAssembler::RegisterFrameAddress(
interpreter::Register interpreter_register, Register rscratch) {
return __ add(rscratch, fp,
Operand(interpreter_register.ToOperand() * kSystemPointerSize));
}
MemOperand BaselineAssembler::FeedbackVectorOperand() {
return MemOperand(fp, BaselineFrameConstants::kFeedbackVectorFromFp);
}
......
......@@ -79,6 +79,11 @@ MemOperand BaselineAssembler::RegisterFrameOperand(
interpreter::Register interpreter_register) {
return MemOperand(fp, interpreter_register.ToOperand() * kSystemPointerSize);
}
void BaselineAssembler::RegisterFrameAddress(
interpreter::Register interpreter_register, Register rscratch) {
return __ Add(rscratch, fp,
interpreter_register.ToOperand() * kSystemPointerSize);
}
MemOperand BaselineAssembler::FeedbackVectorOperand() {
return MemOperand(fp, BaselineFrameConstants::kFeedbackVectorFromFp);
}
......
......@@ -26,6 +26,8 @@ class BaselineAssembler {
explicit BaselineAssembler(MacroAssembler* masm) : masm_(masm) {}
inline static MemOperand RegisterFrameOperand(
interpreter::Register interpreter_register);
inline void RegisterFrameAddress(interpreter::Register interpreter_register,
Register rscratch);
inline MemOperand ContextOperand();
inline MemOperand FunctionOperand();
inline MemOperand FeedbackVectorOperand();
......
......@@ -1326,6 +1326,20 @@ void BaselineCompiler::VisitIntrinsicCopyDataProperties(
CallBuiltin<Builtin::kCopyDataProperties>(args);
}
void BaselineCompiler::
VisitIntrinsicCopyDataPropertiesWithExcludedPropertiesOnStack(
interpreter::RegisterList args) {
BaselineAssembler::ScratchRegisterScope scratch_scope(&basm_);
Register rscratch = scratch_scope.AcquireScratch();
if (args.register_count() != 1) {
basm_.RegisterFrameAddress(args[1], rscratch);
} else {
basm_.Move(rscratch, 0);
}
CallBuiltin<Builtin::kCopyDataPropertiesWithExcludedPropertiesOnStack>(
args[0], args.register_count() - 1, rscratch);
}
void BaselineCompiler::VisitIntrinsicCreateIterResultObject(
interpreter::RegisterList args) {
CallBuiltin<Builtin::kCreateIterResultObject>(args);
......
......@@ -84,6 +84,11 @@ MemOperand BaselineAssembler::RegisterFrameOperand(
interpreter::Register interpreter_register) {
return MemOperand(ebp, interpreter_register.ToOperand() * kSystemPointerSize);
}
void BaselineAssembler::RegisterFrameAddress(
interpreter::Register interpreter_register, Register rscratch) {
return __ lea(rscratch, MemOperand(ebp, interpreter_register.ToOperand() *
kSystemPointerSize));
}
MemOperand BaselineAssembler::FeedbackVectorOperand() {
return MemOperand(ebp, BaselineFrameConstants::kFeedbackVectorFromFp);
}
......
......@@ -78,6 +78,11 @@ MemOperand BaselineAssembler::RegisterFrameOperand(
interpreter::Register interpreter_register) {
return MemOperand(fp, interpreter_register.ToOperand() * kSystemPointerSize);
}
void BaselineAssembler::RegisterFrameAddress(
interpreter::Register interpreter_register, Register rscratch) {
return __ Add_d(rscratch, fp,
interpreter_register.ToOperand() * kSystemPointerSize);
}
MemOperand BaselineAssembler::FeedbackVectorOperand() {
return MemOperand(fp, BaselineFrameConstants::kFeedbackVectorFromFp);
}
......
......@@ -80,6 +80,11 @@ MemOperand BaselineAssembler::RegisterFrameOperand(
interpreter::Register interpreter_register) {
return MemOperand(fp, interpreter_register.ToOperand() * kSystemPointerSize);
}
void BaselineAssembler::RegisterFrameAddress(
interpreter::Register interpreter_register, Register rscratch) {
return __ Addu(rscratch, fp,
interpreter_register.ToOperand() * kSystemPointerSize);
}
MemOperand BaselineAssembler::FeedbackVectorOperand() {
return MemOperand(fp, BaselineFrameConstants::kFeedbackVectorFromFp);
}
......
......@@ -78,6 +78,11 @@ MemOperand BaselineAssembler::RegisterFrameOperand(
interpreter::Register interpreter_register) {
return MemOperand(fp, interpreter_register.ToOperand() * kSystemPointerSize);
}
void BaselineAssembler::RegisterFrameAddress(
interpreter::Register interpreter_register, Register rscratch) {
return __ Daddu(rscratch, fp,
interpreter_register.ToOperand() * kSystemPointerSize);
}
MemOperand BaselineAssembler::FeedbackVectorOperand() {
return MemOperand(fp, BaselineFrameConstants::kFeedbackVectorFromFp);
}
......
......@@ -83,6 +83,10 @@ MemOperand BaselineAssembler::RegisterFrameOperand(
UNIMPLEMENTED();
return MemOperand(fp, interpreter_register.ToOperand() * kSystemPointerSize);
}
void BaselineAssembler::RegisterFrameAddress(
interpreter::Register interpreter_register, Register rscratch) {
UNIMPLEMENTED();
}
MemOperand BaselineAssembler::FeedbackVectorOperand() {
UNIMPLEMENTED();
return MemOperand(fp, BaselineFrameConstants::kFeedbackVectorFromFp);
......
......@@ -76,6 +76,11 @@ MemOperand BaselineAssembler::RegisterFrameOperand(
interpreter::Register interpreter_register) {
return MemOperand(fp, interpreter_register.ToOperand() * kSystemPointerSize);
}
void BaselineAssembler::RegisterFrameAddress(
interpreter::Register interpreter_register, Register rscratch) {
return __ Add64(rscratch, fp,
interpreter_register.ToOperand() * kSystemPointerSize);
}
MemOperand BaselineAssembler::FeedbackVectorOperand() {
return MemOperand(fp, BaselineFrameConstants::kFeedbackVectorFromFp);
}
......
......@@ -153,6 +153,11 @@ MemOperand BaselineAssembler::RegisterFrameOperand(
interpreter::Register interpreter_register) {
return MemOperand(fp, interpreter_register.ToOperand() * kSystemPointerSize);
}
void BaselineAssembler::RegisterFrameAddress(
interpreter::Register interpreter_register, Register rscratch) {
return __ AddS64(rscratch, fp,
interpreter_register.ToOperand() * kSystemPointerSize);
}
MemOperand BaselineAssembler::FeedbackVectorOperand() {
return MemOperand(fp, BaselineFrameConstants::kFeedbackVectorFromFp);
}
......
......@@ -86,6 +86,11 @@ MemOperand BaselineAssembler::RegisterFrameOperand(
interpreter::Register interpreter_register) {
return MemOperand(rbp, interpreter_register.ToOperand() * kSystemPointerSize);
}
void BaselineAssembler::RegisterFrameAddress(
interpreter::Register interpreter_register, Register rscratch) {
return __ leaq(rscratch, MemOperand(rbp, interpreter_register.ToOperand() *
kSystemPointerSize));
}
MemOperand BaselineAssembler::FeedbackVectorOperand() {
return MemOperand(rbp, BaselineFrameConstants::kFeedbackVectorFromFp);
}
......
......@@ -317,6 +317,10 @@ namespace internal {
/* ES #sec-copydataproperties */ \
TFS(CopyDataProperties, kTarget, kSource) \
TFS(SetDataProperties, kTarget, kSource) \
TFC(CopyDataPropertiesWithExcludedPropertiesOnStack, \
CopyDataPropertiesWithExcludedPropertiesOnStack) \
TFC(CopyDataPropertiesWithExcludedProperties, \
CopyDataPropertiesWithExcludedProperties) \
\
/* Abort */ \
TFC(Abort, Abort) \
......
......@@ -765,9 +765,20 @@ class SetOrCopyDataPropertiesAssembler : public CodeStubAssembler {
: CodeStubAssembler(state) {}
protected:
TNode<Object> SetOrCopyDataProperties(TNode<Context> context,
TNode<JSReceiver> target,
TNode<Object> source, Label* if_runtime,
TNode<JSObject> AllocateJsObjectTarget(TNode<Context> context) {
const TNode<NativeContext> native_context = LoadNativeContext(context);
const TNode<JSFunction> object_function = Cast(
LoadContextElement(native_context, Context::OBJECT_FUNCTION_INDEX));
const TNode<Map> map =
Cast(LoadJSFunctionPrototypeOrInitialMap(object_function));
const TNode<JSObject> target = AllocateJSObjectFromMap(map);
return target;
}
TNode<Object> SetOrCopyDataProperties(
TNode<Context> context, TNode<JSReceiver> target, TNode<Object> source,
Label* if_runtime,
base::Optional<TNode<IntPtrT>> excluded_property_count = base::nullopt,
base::Optional<TNode<IntPtrT>> excluded_property_base = base::nullopt,
bool use_set = true) {
Label if_done(this), if_noelements(this),
if_sourcenotjsobject(this, Label::kDeferred);
......@@ -791,12 +802,12 @@ class SetOrCopyDataPropertiesAssembler : public CodeStubAssembler {
BIND(&if_noelements);
{
// If the target is deprecated, the object will be updated on first store.
// If the source for that store equals the target, this will invalidate
// the cached representation of the source. Handle this case in runtime.
// If the target is deprecated, the object will be updated on first
// store. If the source for that store equals the target, this will
// invalidate the cached representation of the source. Handle this case
// in runtime.
TNode<Map> target_map = LoadMap(target);
GotoIf(IsDeprecatedMap(target_map), if_runtime);
if (use_set) {
TNode<BoolT> target_is_simple_receiver = IsSimpleObjectMap(target_map);
ForEachEnumerableOwnProperty(
......@@ -811,8 +822,27 @@ class SetOrCopyDataPropertiesAssembler : public CodeStubAssembler {
ForEachEnumerableOwnProperty(
context, source_map, CAST(source), kEnumerationOrder,
[=](TNode<Name> key, TNode<Object> value) {
Label skip(this);
if (excluded_property_count.has_value()) {
BuildFastLoop<IntPtrT>(
IntPtrConstant(0), excluded_property_count.value(),
[&](TNode<IntPtrT> index) {
auto offset = Signed(TimesSystemPointerSize(index));
TNode<IntPtrT> location = Signed(
IntPtrSub(excluded_property_base.value(), offset));
auto property = LoadFullTagged(location);
Label continue_label(this);
BranchIfSameValue(key, property, &skip, &continue_label);
Bind(&continue_label);
},
1, IndexAdvanceMode::kPost);
}
CallBuiltin(Builtin::kSetPropertyInLiteral, context, target, key,
value);
Goto(&skip);
Bind(&skip);
},
if_runtime);
}
......@@ -833,12 +863,61 @@ class SetOrCopyDataPropertiesAssembler : public CodeStubAssembler {
}
BIND(&if_done);
return UndefinedConstant();
return target;
}
};
} // namespace
TF_BUILTIN(CopyDataPropertiesWithExcludedPropertiesOnStack,
SetOrCopyDataPropertiesAssembler) {
auto source = UncheckedParameter<Object>(Descriptor::kSource);
auto excluded_property_count =
UncheckedParameter<IntPtrT>(Descriptor::kExcludedPropertyCount);
auto excluded_properties =
UncheckedParameter<IntPtrT>(Descriptor::kExcludedPropertyBase);
auto context = Parameter<Context>(Descriptor::kContext);
// first check undefine or null
Label if_runtime(this, Label::kDeferred);
GotoIf(IsNullOrUndefined(source), &if_runtime);
TNode<JSReceiver> target = AllocateJsObjectTarget(context);
Return(SetOrCopyDataProperties(context, target, source, &if_runtime,
excluded_property_count, excluded_properties,
false));
BIND(&if_runtime);
TNode<Foreign> excluded_properties_foreign =
TNode<Foreign>::UncheckedCast(CallRuntime(Runtime::kNewForeign, context));
StoreForeignForeignAddress(
excluded_properties_foreign,
ReinterpretCast<ExternalPointerT>(excluded_properties));
TailCallRuntime(Runtime::kCopyDataPropertiesWithExcludedPropertiesOnStack,
context, source, SmiTag(excluded_property_count),
excluded_properties_foreign);
}
TF_BUILTIN(CopyDataPropertiesWithExcludedProperties,
SetOrCopyDataPropertiesAssembler) {
auto source = UncheckedParameter<Object>(Descriptor::kSource);
auto excluded_property_count_smi =
UncheckedParameter<Smi>(Descriptor::kExcludedPropertyCount);
auto context = Parameter<Context>(Descriptor::kContext);
auto excluded_property_count = SmiToIntPtr(excluded_property_count_smi);
CodeStubArguments arguments(this, excluded_property_count);
TNode<IntPtrT> excluded_properties =
ReinterpretCast<IntPtrT>(arguments.AtIndexPtr(
IntPtrSub(excluded_property_count, IntPtrConstant(2))));
arguments.PopAndReturn(CallBuiltin(
Builtin::kCopyDataPropertiesWithExcludedPropertiesOnStack, context,
source, excluded_property_count, excluded_properties));
}
// ES #sec-copydataproperties
TF_BUILTIN(CopyDataProperties, SetOrCopyDataPropertiesAssembler) {
auto target = Parameter<JSObject>(Descriptor::kTarget);
......@@ -848,7 +927,9 @@ TF_BUILTIN(CopyDataProperties, SetOrCopyDataPropertiesAssembler) {
CSA_DCHECK(this, TaggedNotEqual(target, source));
Label if_runtime(this, Label::kDeferred);
Return(SetOrCopyDataProperties(context, target, source, &if_runtime, false));
SetOrCopyDataProperties(context, target, source, &if_runtime, base::nullopt,
base::nullopt, false);
Return(UndefinedConstant());
BIND(&if_runtime);
TailCallRuntime(Runtime::kCopyDataProperties, context, target, source);
......@@ -861,7 +942,9 @@ TF_BUILTIN(SetDataProperties, SetOrCopyDataPropertiesAssembler) {
Label if_runtime(this, Label::kDeferred);
GotoIfForceSlowPath(&if_runtime);
Return(SetOrCopyDataProperties(context, target, source, &if_runtime, true));
SetOrCopyDataProperties(context, target, source, &if_runtime, base::nullopt,
base::nullopt, true);
Return(UndefinedConstant());
BIND(&if_runtime);
TailCallRuntime(Runtime::kSetDataProperties, context, target, source);
......
......@@ -145,6 +145,22 @@ constexpr auto CallTrampolineDescriptor::registers() {
return RegisterArray(r1, r0);
}
// static
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// r0 : the source
// r1 : the excluded property count
return RegisterArray(r1, r0);
}
// static
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// r0 : the source
// r1 : the excluded property count
// r2 : the excluded property base
return RegisterArray(r1, r0, r2);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// r0 : number of arguments (on the stack)
......
......@@ -145,6 +145,20 @@ constexpr auto CallTrampolineDescriptor::registers() {
return RegisterArray(x1, x0);
}
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// r1 : the source
// r0 : the excluded property count
return RegisterArray(x1, x0);
}
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// r1 : the source
// r0 : the excluded property count
// x2 : the excluded property base
return RegisterArray(x1, x0, x2);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// x0 : number of arguments (on the stack)
......
......@@ -144,6 +144,22 @@ constexpr auto CallTrampolineDescriptor::registers() {
return RegisterArray(edi, eax);
}
// static
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// edi : the source
// eax : the excluded property count
return RegisterArray(edi, eax);
}
// static
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// edi : the source
// eax : the excluded property count
// ecx : the excluded property base
return RegisterArray(edi, eax, ecx);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// eax : number of arguments (on the stack)
......
......@@ -39,6 +39,8 @@ namespace internal {
V(BinaryOp_WithFeedback) \
V(CallForwardVarargs) \
V(CallFunctionTemplate) \
V(CopyDataPropertiesWithExcludedProperties) \
V(CopyDataPropertiesWithExcludedPropertiesOnStack) \
V(CallTrampoline) \
V(CallTrampoline_Baseline) \
V(CallTrampoline_Baseline_Compact) \
......@@ -1251,6 +1253,31 @@ class CallTrampolineDescriptor
static constexpr inline auto registers();
};
class CopyDataPropertiesWithExcludedPropertiesDescriptor
: public StaticCallInterfaceDescriptor<
CopyDataPropertiesWithExcludedPropertiesDescriptor> {
public:
DEFINE_PARAMETERS_VARARGS(kSource, kExcludedPropertyCount)
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kSource
MachineType::AnyTagged()) // kExcludedPropertyCount
DECLARE_DESCRIPTOR(CopyDataPropertiesWithExcludedPropertiesDescriptor)
static constexpr inline auto registers();
};
class CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor
: public StaticCallInterfaceDescriptor<
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor> {
public:
DEFINE_PARAMETERS(kSource, kExcludedPropertyCount, kExcludedPropertyBase)
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kSource
MachineType::IntPtr(),
MachineType::IntPtr()) // kExcludedPropertyCount
DECLARE_DESCRIPTOR(CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor)
static constexpr inline auto registers();
};
class CallVarargsDescriptor
: public StaticCallInterfaceDescriptor<CallVarargsDescriptor> {
public:
......
......@@ -145,6 +145,22 @@ constexpr auto CallTrampolineDescriptor::registers() {
return RegisterArray(a1, a0);
}
// static
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// a1 : the source
// a0 : the excluded property count
return RegisterArray(a1, a0);
}
// static
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// a1 : the source
// a0 : the excluded property count
// a2 : the excluded property base
return RegisterArray(a1, a0, a2);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// a0 : number of arguments (on the stack)
......
......@@ -144,6 +144,22 @@ constexpr auto CallTrampolineDescriptor::registers() {
return RegisterArray(a1, a0);
}
// static
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// a1 : the source
// a0 : the excluded property count
return RegisterArray(a1, a0);
}
// static
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// a1 : the source
// a0 : the excluded property count
// a2 : the excluded property base
return RegisterArray(a1, a0, a2);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// a0 : number of arguments (on the stack)
......
......@@ -145,6 +145,22 @@ constexpr auto CallTrampolineDescriptor::registers() {
return RegisterArray(a1, a0);
}
// static
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// a1 : the source
// a0 : the excluded property count
return RegisterArray(a1, a0);
}
// static
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// a1 : the source
// a0 : the excluded property count
// a2 : the excluded property base
return RegisterArray(a1, a0, a2);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// a0 : number of arguments (on the stack)
......
......@@ -149,6 +149,22 @@ constexpr auto CallTrampolineDescriptor::registers() {
return RegisterArray(r4, r3);
}
// static
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// r4 : the source
// r3 : the excluded property count
return RegisterArray(r4, r3);
}
// static
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// r4 : the source
// r3 : the excluded property count
// r5 : the excluded property base
return RegisterArray(r4, r3, r5);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// r3 : number of arguments (on the stack)
......
......@@ -146,6 +146,22 @@ constexpr auto CallTrampolineDescriptor::registers() {
return RegisterArray(a1, a0);
}
// static
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// a1 : the source
// a0 : the excluded property count
return RegisterArray(a1, a0);
}
// static
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// a1 : the source
// a0 : the excluded property count
// a2 : the excluded property base
return RegisterArray(a1, a0, a2);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// a0 : number of arguments (on the stack)
......
......@@ -149,6 +149,22 @@ constexpr auto CallTrampolineDescriptor::registers() {
return RegisterArray(r3, r2);
}
// static
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// r3 : the source
// r2 : the excluded property count
return RegisterArray(r3, r2);
}
// static
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// r3 : the source
// r2 : the excluded property count
// r4 : the excluded property base
return RegisterArray(r3, r2, r4);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// r2 : number of arguments (on the stack)
......
......@@ -169,6 +169,21 @@ constexpr auto CallTrampolineDescriptor::registers() {
// rdi : the target to call
return RegisterArray(rdi, rax);
}
// static
constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
// rdi : the source
// rax : the excluded property count
return RegisterArray(rdi, rax);
}
// static
constexpr auto
CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
// rdi : the source
// rax : the excluded property count
// rcx : the excluded property base
return RegisterArray(rdi, rax, rcx);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
......
......@@ -44,6 +44,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
switch (f->function_id) {
case Runtime::kInlineCopyDataProperties:
return ReduceCopyDataProperties(node);
case Runtime::kInlineCopyDataPropertiesWithExcludedPropertiesOnStack:
return ReduceCopyDataPropertiesWithExcludedPropertiesOnStack(node);
case Runtime::kInlineCreateIterResultObject:
return ReduceCreateIterResultObject(node);
case Runtime::kInlineDeoptimizeNow:
......@@ -89,6 +91,25 @@ Reduction JSIntrinsicLowering::ReduceCopyDataProperties(Node* node) {
node, Builtins::CallableFor(isolate(), Builtin::kCopyDataProperties), 0);
}
Reduction
JSIntrinsicLowering::ReduceCopyDataPropertiesWithExcludedPropertiesOnStack(
Node* node) {
int input_count =
static_cast<int>(CallRuntimeParametersOf(node->op()).arity());
CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
auto callable = Builtins::CallableFor(
isolate(), Builtin::kCopyDataPropertiesWithExcludedProperties);
auto call_descriptor = Linkage::GetStubCallDescriptor(
graph()->zone(), callable.descriptor(), input_count - 1, flags,
node->op()->properties());
node->InsertInput(graph()->zone(), 0,
jsgraph()->HeapConstant(callable.code()));
node->InsertInput(graph()->zone(), 2,
jsgraph()->SmiConstant(input_count - 1));
NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
return Changed(node);
}
Reduction JSIntrinsicLowering::ReduceCreateIterResultObject(Node* node) {
Node* const value = NodeProperties::GetValueInput(node, 0);
Node* const done = NodeProperties::GetValueInput(node, 1);
......@@ -254,12 +275,10 @@ Reduction JSIntrinsicLowering::ReduceIsInstanceType(
vfalse, merge);
}
Reduction JSIntrinsicLowering::ReduceIsJSReceiver(Node* node) {
return Change(node, simplified()->ObjectIsReceiver());
}
Reduction JSIntrinsicLowering::ReduceTurbofanStaticAssert(Node* node) {
if (FLAG_always_opt) {
// Ignore static asserts, as we most likely won't have enough information
......@@ -293,19 +312,16 @@ Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op) {
return Changed(node);
}
Reduction JSIntrinsicLowering::ReduceToLength(Node* node) {
NodeProperties::ChangeOp(node, javascript()->ToLength());
return Changed(node);
}
Reduction JSIntrinsicLowering::ReduceToObject(Node* node) {
NodeProperties::ChangeOp(node, javascript()->ToObject());
return Changed(node);
}
Reduction JSIntrinsicLowering::ReduceToString(Node* node) {
// ToString is unnecessary if the input is a string.
HeapObjectMatcher m(NodeProperties::GetValueInput(node, 0));
......@@ -317,7 +333,6 @@ Reduction JSIntrinsicLowering::ReduceToString(Node* node) {
return Changed(node);
}
Reduction JSIntrinsicLowering::ReduceCall(Node* node) {
int const arity =
static_cast<int>(CallRuntimeParametersOf(node->op()).arity());
......@@ -354,7 +369,6 @@ Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
return Changed(node);
}
Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
Node* b, Node* c) {
RelaxControls(node);
......@@ -366,7 +380,6 @@ Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
return Changed(node);
}
Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
Node* b, Node* c, Node* d) {
RelaxControls(node);
......@@ -396,10 +409,8 @@ Reduction JSIntrinsicLowering::Change(Node* node, Callable const& callable,
Graph* JSIntrinsicLowering::graph() const { return jsgraph()->graph(); }
Isolate* JSIntrinsicLowering::isolate() const { return jsgraph()->isolate(); }
CommonOperatorBuilder* JSIntrinsicLowering::common() const {
return jsgraph()->common();
}
......
......@@ -40,6 +40,7 @@ class V8_EXPORT_PRIVATE JSIntrinsicLowering final
private:
Reduction ReduceCopyDataProperties(Node* node);
Reduction ReduceCopyDataPropertiesWithExcludedPropertiesOnStack(Node* node);
Reduction ReduceCreateIterResultObject(Node* node);
Reduction ReduceDeoptimizeNow(Node* node);
Reduction ReduceCreateJSGeneratorObject(Node* node);
......
......@@ -4300,7 +4300,8 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment(
// rest_runtime_callargs[2] = temp1;
// a() = value[temp1];
//
// b.c = %CopyDataPropertiesWithExcludedProperties.call(rest_runtime_callargs);
// b.c =
// %CopyDataPropertiesWithExcludedPropertiesOnStack.call(rest_runtime_callargs);
void BytecodeGenerator::BuildDestructuringObjectAssignment(
ObjectLiteral* pattern, Token::Value op,
LookupHoistingMode lookup_hoisting_mode) {
......@@ -4406,7 +4407,8 @@ void BytecodeGenerator::BuildDestructuringObjectAssignment(
DCHECK_EQ(i, pattern->properties()->length() - 1);
DCHECK(!value_key.is_valid());
DCHECK_NULL(value_name);
builder()->CallRuntime(Runtime::kCopyDataPropertiesWithExcludedProperties,
builder()->CallRuntime(
Runtime::kInlineCopyDataPropertiesWithExcludedPropertiesOnStack,
rest_runtime_callargs);
} else if (value_name) {
builder()->LoadNamedProperty(
......
......@@ -139,6 +139,21 @@ TNode<Object> IntrinsicsGenerator::CopyDataProperties(
arg_count);
}
TNode<Object>
IntrinsicsGenerator::CopyDataPropertiesWithExcludedPropertiesOnStack(
const InterpreterAssembler::RegListNodePair& args, TNode<Context> context,
int arg_count) {
TNode<IntPtrT> offset = __ TimesSystemPointerSize(__ IntPtrConstant(1));
auto base = __ Signed(__ IntPtrSub(args.base_reg_location(), offset));
Callable callable = Builtins::CallableFor(
isolate_, Builtin::kCopyDataPropertiesWithExcludedPropertiesOnStack);
TNode<IntPtrT> excluded_property_count = __ IntPtrSub(
__ ChangeInt32ToIntPtr(args.reg_count()), __ IntPtrConstant(1));
return __ CallStub(callable, context,
__ LoadRegisterFromRegisterList(args, 0),
excluded_property_count, base);
}
TNode<Object> IntrinsicsGenerator::CreateIterResultObject(
const InterpreterAssembler::RegListNodePair& args, TNode<Context> context,
int arg_count) {
......
......@@ -29,6 +29,8 @@ namespace interpreter {
V(GeneratorClose, generator_close, 1) \
V(GetImportMetaObject, get_import_meta_object, 0) \
V(CopyDataProperties, copy_data_properties, 2) \
V(CopyDataPropertiesWithExcludedPropertiesOnStack, \
copy_data_properties_with_excluded_properties_on_stack, -1) \
V(CreateIterResultObject, create_iter_result_object, 2) \
V(CreateAsyncFromSyncIterator, create_async_from_sync_iterator, 1)
......
......@@ -220,6 +220,12 @@ RUNTIME_FUNCTION(Runtime_NewError) {
return *isolate->factory()->NewError(message_template, arg0);
}
RUNTIME_FUNCTION(Runtime_NewForeign) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
return *isolate->factory()->NewForeign(kNullAddress);
}
RUNTIME_FUNCTION(Runtime_NewTypeError) {
HandleScope scope(isolate);
DCHECK_LE(args.length(), 4);
......
......@@ -1291,10 +1291,16 @@ RUNTIME_FUNCTION(Runtime_CopyDataProperties) {
return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedProperties) {
RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedPropertiesOnStack) {
HandleScope scope(isolate);
DCHECK_LE(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, source, 0);
CONVERT_ARG_HANDLE_CHECKED(Smi, excluded_property_count_smi, 1);
CONVERT_ARG_HANDLE_CHECKED(Foreign, excluded_property_base_foreign, 2);
int excluded_property_count = excluded_property_count_smi->value();
auto excluded_property_base = reinterpret_cast<Address*>(
excluded_property_base_foreign->foreign_address());
// If source is undefined or null, throw a non-coercible error.
if (source->IsNullOrUndefined(isolate)) {
......@@ -1302,9 +1308,12 @@ RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedProperties) {
MaybeHandle<Object>());
}
base::ScopedVector<Handle<Object>> excluded_properties(args.length() - 1);
for (int i = 1; i < args.length(); i++) {
Handle<Object> property = args.at(i);
base::ScopedVector<Handle<Object>> excluded_properties(
excluded_property_count);
for (int i = 0; i < excluded_property_count; i++) {
// Because the excluded properties on stack is from high address
// to low address, so we need to use sub
Handle<Object> property(excluded_property_base - i);
uint32_t property_num;
// We convert string to number if possible, in cases of computed
// properties resolving to numbers, which would've been strings
......@@ -1315,7 +1324,7 @@ RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedProperties) {
property = isolate->factory()->NewNumberFromUint(property_num);
}
excluded_properties[i - 1] = property;
excluded_properties[i] = property;
}
Handle<JSObject> target =
......
......@@ -225,6 +225,7 @@ namespace internal {
F(BytecodeBudgetInterrupt, 1, 1) \
F(BytecodeBudgetInterruptWithStackCheck, 1, 1) \
F(NewError, 2, 1) \
F(NewForeign, 0, 1) \
F(NewReferenceError, 2, 1) \
F(NewSyntaxError, 2, 1) \
F(NewTypeError, -1 /* [1, 4] */, 1) \
......@@ -293,7 +294,7 @@ namespace internal {
F(CollectTypeProfile, 3, 1) \
F(CompleteInobjectSlackTrackingForMap, 1, 1) \
I(CopyDataProperties, 2, 1) \
F(CopyDataPropertiesWithExcludedProperties, -1 /* >= 1 */, 1) \
I(CopyDataPropertiesWithExcludedPropertiesOnStack, -1 /* >= 1 */, 1) \
I(CreateDataProperty, 3, 1) \
I(CreateIterResultObject, 2, 1) \
F(CreatePrivateAccessors, 2, 1) \
......
......@@ -380,7 +380,7 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 29
bytecode array length: 28
bytecodes: [
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
B(Star1),
......@@ -391,7 +391,7 @@ bytecodes: [
B(JumpIfNotUndefined), U8(3),
B(LdaZero),
B(Star0),
/* 71 S> */ B(CallRuntime), U16(Runtime::kCopyDataPropertiesWithExcludedProperties), R(2), U8(2),
/* 71 S> */ B(InvokeIntrinsic), U8(Runtime::k_CopyDataPropertiesWithExcludedPropertiesOnStack), R(2), U8(2),
B(StaGlobal), U8(2), U8(3),
B(LdaUndefined),
/* 80 S> */ B(Return),
......
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