Commit 1413f07b authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[csa] Add ToObject_Inline macro

This CL adds a ToObject_Inline CSA macro that avoids the "ToObject"
builtin call if the passed argument is already a JSReceiver.

The CL also replaces all occurences of ToObject in Torque code with
ToObject_Inline.

R=jgruber@chromium.org

Change-Id: I1cd66d5d51dde5a93d9a0c55489b13a6f4ba9dc2
Reviewed-on: https://chromium-review.googlesource.com/1169819
Commit-Queue: Simon Zünd <szuend@google.com>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55039}
parent f642de00
......@@ -11,7 +11,7 @@ module array {
javascript builtin ArrayPrototypeCopyWithin(
context: Context, receiver: Object, ...arguments): Object {
// 1. Let O be ? ToObject(this value).
const object: JSReceiver = ToObject(context, receiver);
const object: JSReceiver = ToObject_Inline(context, receiver);
// 2. Let len be ? ToLength(? Get(O, "length")).
const length: Number = GetLengthProperty(context, object);
......
......@@ -143,7 +143,7 @@ module array {
}
// 1. Let O be ? ToObject(this value).
const o: JSReceiver = ToObject(context, receiver);
const o: JSReceiver = ToObject_Inline(context, receiver);
// 2. Let len be ? ToLength(? Get(O, "length")).
const len: Number = GetLengthProperty(context, o);
......
......@@ -194,6 +194,7 @@ extern macro ArraySpeciesCreate(Context, Object, Number): Object;
extern macro EnsureArrayPushable(Map): ElementsKind labels Bailout;
extern builtin ToObject(Context, Object): JSReceiver;
extern macro ToObject_Inline(Context, Object): JSReceiver;
extern macro IsNullOrUndefined(Object): bool;
extern macro IsTheHole(Object): bool;
extern macro IsString(HeapObject): bool;
......
......@@ -440,7 +440,7 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
// 1. Let O be ToObject(this value).
// 2. ReturnIfAbrupt(O)
o_ = ToObject(context(), receiver());
o_ = ToObject_Inline(context(), receiver());
// 3. Let len be ToLength(Get(O, "length")).
// 4. ReturnIfAbrupt(len).
......@@ -1395,7 +1395,7 @@ TF_BUILTIN(ArrayPrototypeSlice, ArrayPrototypeSliceCodeStubAssembler) {
BIND(&generic_length);
// 1. Let O be ToObject(this value).
// 2. ReturnIfAbrupt(O).
o = ToObject(context, receiver);
o = ToObject_Inline(context, receiver);
// 3. Let len be ToLength(Get(O, "length")).
// 4. ReturnIfAbrupt(len).
......@@ -2047,7 +2047,7 @@ TF_BUILTIN(ArrayFrom, ArrayPopulatorAssembler) {
TNode<Object> items = args.GetOptionalArgumentValue(0);
// The spec doesn't require ToObject to be called directly on the iterable
// branch, but it's part of GetMethod that is in the spec.
TNode<JSReceiver> array_like = ToObject(context, items);
TNode<JSReceiver> array_like = ToObject_Inline(context, items);
TVARIABLE(Object, array);
TVARIABLE(Number, length);
......@@ -3490,7 +3490,7 @@ TF_BUILTIN(ArrayIndexOfHoleyDoubles, ArrayIncludesIndexofAssembler) {
TF_BUILTIN(ArrayPrototypeValues, CodeStubAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
Return(CreateArrayIterator(context, ToObject(context, receiver),
Return(CreateArrayIterator(context, ToObject_Inline(context, receiver),
IterationKind::kValues));
}
......@@ -3498,7 +3498,7 @@ TF_BUILTIN(ArrayPrototypeValues, CodeStubAssembler) {
TF_BUILTIN(ArrayPrototypeEntries, CodeStubAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
Return(CreateArrayIterator(context, ToObject(context, receiver),
Return(CreateArrayIterator(context, ToObject_Inline(context, receiver),
IterationKind::kEntries));
}
......@@ -3506,7 +3506,7 @@ TF_BUILTIN(ArrayPrototypeEntries, CodeStubAssembler) {
TF_BUILTIN(ArrayPrototypeKeys, CodeStubAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
Return(CreateArrayIterator(context, ToObject(context, receiver),
Return(CreateArrayIterator(context, ToObject_Inline(context, receiver),
IterationKind::kKeys));
}
......@@ -3976,7 +3976,7 @@ TF_BUILTIN(ArrayPrototypeFlat, CodeStubAssembler) {
Node* const depth = args.GetOptionalArgumentValue(0);
// 1. Let O be ? ToObject(this value).
Node* const o = ToObject(context, receiver);
Node* const o = ToObject_Inline(CAST(context), CAST(receiver));
// 2. Let sourceLen be ? ToLength(? Get(O, "length")).
Node* const source_length =
......@@ -4019,7 +4019,7 @@ TF_BUILTIN(ArrayPrototypeFlatMap, CodeStubAssembler) {
Node* const mapper_function = args.GetOptionalArgumentValue(0);
// 1. Let O be ? ToObject(this value).
Node* const o = ToObject(context, receiver);
Node* const o = ToObject_Inline(CAST(context), CAST(receiver));
// 2. Let sourceLen be ? ToLength(? Get(O, "length")).
Node* const source_length =
......
......@@ -200,7 +200,7 @@ TNode<Uint32T> ObjectEntriesValuesBuiltinsAssembler::HasHiddenPrototype(
void ObjectEntriesValuesBuiltinsAssembler::GetOwnValuesOrEntries(
TNode<Context> context, TNode<Object> maybe_object,
CollectType collect_type) {
TNode<JSReceiver> receiver = ToObject(context, maybe_object);
TNode<JSReceiver> receiver = ToObject_Inline(context, maybe_object);
Label if_call_runtime_with_fast_path(this, Label::kDeferred),
if_call_runtime(this, Label::kDeferred),
......@@ -493,7 +493,7 @@ TF_BUILTIN(ObjectAssign, ObjectBuiltinsAssembler) {
TNode<Object> target = args.GetOptionalArgumentValue(0);
// 1. Let to be ? ToObject(target).
TNode<JSReceiver> to = ToObject(context, target);
TNode<JSReceiver> to = ToObject_Inline(context, target);
Label done(this);
// 2. If only one argument was passed, return to.
......@@ -1222,10 +1222,10 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) {
// ES6 #sec-object.prototype.valueof
TF_BUILTIN(ObjectPrototypeValueOf, CodeStubAssembler) {
Node* receiver = Parameter(Descriptor::kReceiver);
Node* context = Parameter(Descriptor::kContext);
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Return(ToObject(context, receiver));
Return(ToObject_Inline(context, receiver));
}
// ES #sec-object.create
......@@ -1519,7 +1519,7 @@ TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) {
Node* key = args.GetOptionalArgumentValue(1);
// 1. Let obj be ? ToObject(O).
object = ToObject(context, object);
object = ToObject_Inline(CAST(context), CAST(object));
// 2. Let key be ? ToPropertyKey(P).
key = ToName(context, key);
......
......@@ -7028,6 +7028,30 @@ TNode<JSReceiver> CodeStubAssembler::ToObject(SloppyTNode<Context> context,
return CAST(CallBuiltin(Builtins::kToObject, context, input));
}
TNode<JSReceiver> CodeStubAssembler::ToObject_Inline(TNode<Context> context,
TNode<Object> input) {
TVARIABLE(JSReceiver, result);
Label if_isreceiver(this), if_isnotreceiver(this, Label::kDeferred);
Label done(this);
BranchIfJSReceiver(input, &if_isreceiver, &if_isnotreceiver);
BIND(&if_isreceiver);
{
result = CAST(input);
Goto(&done);
}
BIND(&if_isnotreceiver);
{
result = ToObject(context, input);
Goto(&done);
}
BIND(&done);
return result.value();
}
TNode<Smi> CodeStubAssembler::ToSmiIndex(TNode<Object> input,
TNode<Context> context,
Label* range_error) {
......
......@@ -1921,6 +1921,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<JSReceiver> ToObject(SloppyTNode<Context> context,
SloppyTNode<Object> input);
// Same as ToObject but avoids the Builtin call if |input| is already a
// JSReceiver.
TNode<JSReceiver> ToObject_Inline(TNode<Context> context,
TNode<Object> input);
enum ToIntegerTruncationMode {
kNoTruncation,
kTruncateMinusZero,
......
......@@ -1751,7 +1751,7 @@ module array {
}
// 2. Let obj be ? ToObject(this value).
const obj: JSReceiver = ToObject(context, receiver);
const obj: JSReceiver = ToObject_Inline(context, receiver);
let map: Map = obj.map;
const sort_state: FixedArray =
......
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