Commit a360134b authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[ignition] Simplify ForInPrepare by directly using TF builtin

Change-Id: I91bedd8d30e32f270fb528d0d8bbfed45074878f
Reviewed-on: https://chromium-review.googlesource.com/440065Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43103}
parent 504d0e59
......@@ -1000,6 +1000,7 @@ v8_source_set("v8_base") {
"src/builtins/builtins-math.cc",
"src/builtins/builtins-number.cc",
"src/builtins/builtins-object.cc",
"src/builtins/builtins-object.h",
"src/builtins/builtins-promise.cc",
"src/builtins/builtins-promise.h",
"src/builtins/builtins-proxy.cc",
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/builtins/builtins-object.h"
#include "src/builtins/builtins-utils.h"
#include "src/builtins/builtins.h"
#include "src/code-factory.h"
......@@ -11,16 +12,27 @@
namespace v8 {
namespace internal {
class ObjectBuiltinsAssembler : public CodeStubAssembler {
public:
explicit ObjectBuiltinsAssembler(compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {}
typedef compiler::Node Node;
protected:
void IsString(Node* object, Label* if_string, Label* if_notstring);
void ReturnToStringFormat(Node* context, Node* string);
};
std::tuple<Node*, Node*, Node*> ObjectBuiltinsAssembler::EmitForInPrepare(
Node* object, Node* context, Label* call_runtime,
Label* nothing_to_iterate) {
Label use_cache(this);
CSA_ASSERT(this, IsJSReceiver(object));
CheckEnumCache(object, &use_cache, call_runtime);
Bind(&use_cache);
Node* map = LoadMap(object);
Node* enum_length = EnumLength(map);
GotoIf(WordEqual(enum_length, SmiConstant(0)), nothing_to_iterate);
Node* descriptors = LoadMapDescriptors(map);
Node* cache_offset =
LoadObjectField(descriptors, DescriptorArray::kEnumCacheOffset);
Node* enum_cache = LoadObjectField(
cache_offset, DescriptorArray::kEnumCacheBridgeCacheOffset);
return std::make_tuple(map, enum_cache, enum_length);
}
// -----------------------------------------------------------------------------
// ES6 section 19.1 Object Objects
......@@ -931,28 +943,26 @@ TF_BUILTIN(ForInNext, ObjectBuiltinsAssembler) {
TF_BUILTIN(ForInPrepare, ObjectBuiltinsAssembler) {
typedef ForInPrepareDescriptor Descriptor;
Label use_cache(this), nothing_to_iterate(this), call_runtime(this);
Label call_runtime(this), nothing_to_iterate(this);
Node* object = Parameter(Descriptor::kObject);
Node* context = Parameter(Descriptor::kContext);
CheckEnumCache(object, &use_cache, &call_runtime);
Bind(&use_cache);
Node* map = LoadMap(object);
Node* enum_length = EnumLength(map);
GotoIf(WordEqual(enum_length, SmiConstant(0)), &nothing_to_iterate);
Node* descriptors = LoadMapDescriptors(map);
Node* cache_offset =
LoadObjectField(descriptors, DescriptorArray::kEnumCacheOffset);
Node* enum_cache = LoadObjectField(
cache_offset, DescriptorArray::kEnumCacheBridgeCacheOffset);
Return(map, enum_cache, enum_length);
Node* cache_type;
Node* cache_array;
Node* cache_length;
std::tie(cache_type, cache_array, cache_length) =
EmitForInPrepare(object, context, &call_runtime, &nothing_to_iterate);
Bind(&nothing_to_iterate);
Node* zero = SmiConstant(0);
Return(zero, zero, zero);
Return(cache_type, cache_array, cache_length);
Bind(&call_runtime);
TailCallRuntime(Runtime::kForInPrepare, context, object);
Bind(&nothing_to_iterate);
{
Node* zero = SmiConstant(0);
Return(zero, zero, zero);
}
}
TF_BUILTIN(InstanceOf, ObjectBuiltinsAssembler) {
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/code-stub-assembler.h"
namespace v8 {
namespace internal {
class ObjectBuiltinsAssembler : public CodeStubAssembler {
public:
explicit ObjectBuiltinsAssembler(compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {}
std::tuple<Node*, Node*, Node*> EmitForInPrepare(Node* object, Node* context,
Label* call_runtime,
Label* nothing_to_iterate);
protected:
void IsString(Node* object, Label* if_string, Label* if_notstring);
void ReturnToStringFormat(Node* context, Node* string);
};
} // namespace internal
} // namespace v8
......@@ -10,6 +10,7 @@
#include "src/ast/prettyprinter.h"
#include "src/builtins/builtins-arguments.h"
#include "src/builtins/builtins-constructor.h"
#include "src/builtins/builtins-object.h"
#include "src/code-factory.h"
#include "src/compilation-info.h"
#include "src/compiler.h"
......@@ -3088,68 +3089,42 @@ void Interpreter::BuildForInPrepareResult(Node* output_register,
// |cache_info_triple + 2|, with the registers holding cache_type, cache_array,
// and cache_length respectively.
void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) {
Node* object_reg = __ BytecodeOperandReg(0);
Node* receiver = __ LoadRegister(object_reg);
Node* object_register = __ BytecodeOperandReg(0);
Node* output_register = __ BytecodeOperandReg(1);
Node* receiver = __ LoadRegister(object_register);
Node* context = __ GetContext();
Node* const zero_smi = __ SmiConstant(Smi::kZero);
Label nothing_to_iterate(assembler, Label::kDeferred),
use_enum_cache(assembler), use_runtime(assembler, Label::kDeferred);
Node* cache_type;
Node* cache_array;
Node* cache_length;
Label call_runtime(assembler, Label::kDeferred),
nothing_to_iterate(assembler, Label::kDeferred);
if (FLAG_debug_code) {
Label already_receiver(assembler), abort(assembler);
Node* instance_type = __ LoadInstanceType(receiver);
__ Branch(__ IsJSReceiverInstanceType(instance_type), &already_receiver,
&abort);
__ Bind(&abort);
{
__ Abort(kExpectedJSReceiver);
// TODO(klaasb) remove this unreachable Goto once Abort ends the block
__ Goto(&already_receiver);
}
__ Bind(&already_receiver);
}
ObjectBuiltinsAssembler object_assembler(assembler->state());
std::tie(cache_type, cache_array, cache_length) =
object_assembler.EmitForInPrepare(receiver, context, &call_runtime,
&nothing_to_iterate);
__ CheckEnumCache(receiver, &use_enum_cache, &use_runtime);
__ Bind(&use_enum_cache);
{
// The enum cache is valid. Load the map of the object being
// iterated over and use the cache for the iteration.
Node* cache_type = __ LoadMap(receiver);
Node* cache_length = __ EnumLength(cache_type);
__ GotoIf(assembler->WordEqual(cache_length, zero_smi),
&nothing_to_iterate);
Node* descriptors = __ LoadMapDescriptors(cache_type);
Node* cache_offset =
__ LoadObjectField(descriptors, DescriptorArray::kEnumCacheOffset);
Node* cache_array = __ LoadObjectField(
cache_offset, DescriptorArray::kEnumCacheBridgeCacheOffset);
Node* output_register = __ BytecodeOperandReg(1);
BuildForInPrepareResult(output_register, cache_type, cache_array,
cache_length, assembler);
__ Dispatch();
}
BuildForInPrepareResult(output_register, cache_type, cache_array,
cache_length, assembler);
__ Dispatch();
__ Bind(&use_runtime);
__ Bind(&call_runtime);
{
Node* result_triple =
__ CallRuntime(Runtime::kForInPrepare, context, receiver);
Node* cache_type = __ Projection(0, result_triple);
Node* cache_array = __ Projection(1, result_triple);
Node* cache_length = __ Projection(2, result_triple);
Node* output_register = __ BytecodeOperandReg(1);
BuildForInPrepareResult(output_register, cache_type, cache_array,
cache_length, assembler);
__ Dispatch();
}
__ Bind(&nothing_to_iterate);
{
// Receiver is null or undefined or descriptors are zero length.
Node* output_register = __ BytecodeOperandReg(1);
BuildForInPrepareResult(output_register, zero_smi, zero_smi, zero_smi,
assembler);
Node* zero = __ SmiConstant(0);
BuildForInPrepareResult(output_register, zero, zero, zero, assembler);
__ Dispatch();
}
}
......
......@@ -504,6 +504,7 @@
'builtins/builtins-math.cc',
'builtins/builtins-number.cc',
'builtins/builtins-object.cc',
'builtins/builtins-object.h',
'builtins/builtins-promise.cc',
'builtins/builtins-promise.h',
'builtins/builtins-proxy.cc',
......
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