Commit 6c8fc936 authored by vogelheim's avatar vogelheim Committed by Commit bot

Move FastAccessorAssembler from RawMachineAssembler to CodeStubAssembler.

(The goal is to have CodeStubAssembler be the sole assembler-like user of
the TF compiler pipeline; with RMA being a private implementation detail
and FAA being a client.)

BUG=chromium:508898
LOG=Y

Review URL: https://codereview.chromium.org/1674633002

Cr-Commit-Position: refs/heads/master@{#34852}
parent ef6585d8
......@@ -760,8 +760,6 @@ source_set("v8_base") {
"src/compiler/escape-analysis.h",
"src/compiler/escape-analysis-reducer.cc",
"src/compiler/escape-analysis-reducer.h",
"src/compiler/fast-accessor-assembler.cc",
"src/compiler/fast-accessor-assembler.h",
"src/compiler/frame.cc",
"src/compiler/frame.h",
"src/compiler/frame-elider.cc",
......@@ -1023,6 +1021,8 @@ source_set("v8_base") {
"src/extensions/trigger-failure-extension.h",
"src/factory.cc",
"src/factory.h",
"src/fast-accessor-assembler.cc",
"src/fast-accessor-assembler.h",
"src/fast-dtoa.cc",
"src/fast-dtoa.h",
"src/field-index.h",
......
......@@ -21,7 +21,4 @@ specific_include_rules = {
"d8\.cc": [
"+include/libplatform/libplatform.h",
],
"api-experimental\.cc": [
"+src/compiler/fast-accessor-assembler.h",
],
}
......@@ -11,20 +11,17 @@
#include "include/v8.h"
#include "include/v8-experimental.h"
#include "src/api.h"
#include "src/compiler/fast-accessor-assembler.h"
#include "src/fast-accessor-assembler.h"
namespace {
v8::internal::compiler::FastAccessorAssembler* FromApi(
v8::internal::FastAccessorAssembler* FromApi(
v8::experimental::FastAccessorBuilder* builder) {
return reinterpret_cast<v8::internal::compiler::FastAccessorAssembler*>(
builder);
return reinterpret_cast<v8::internal::FastAccessorAssembler*>(builder);
}
v8::experimental::FastAccessorBuilder* FromInternal(
v8::internal::compiler::FastAccessorAssembler* fast_accessor_assembler) {
v8::internal::FastAccessorAssembler* fast_accessor_assembler) {
return reinterpret_cast<v8::experimental::FastAccessorBuilder*>(
fast_accessor_assembler);
}
......@@ -57,8 +54,8 @@ namespace experimental {
FastAccessorBuilder* FastAccessorBuilder::New(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
internal::compiler::FastAccessorAssembler* faa =
new internal::compiler::FastAccessorAssembler(i_isolate);
internal::FastAccessorAssembler* faa =
new internal::FastAccessorAssembler(i_isolate);
return FromInternal(faa);
}
......
......@@ -28,24 +28,27 @@ CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone,
const CallInterfaceDescriptor& descriptor,
Code::Flags flags, const char* name,
size_t result_size)
: raw_assembler_(new RawMachineAssembler(
isolate, new (zone) Graph(zone),
: CodeStubAssembler(
isolate, zone,
Linkage::GetStubCallDescriptor(
isolate, zone, descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), result_size))),
flags_(flags),
name_(name),
code_generated_(false),
variables_(zone) {}
MachineType::AnyTagged(), result_size),
flags, name) {}
CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone,
int parameter_count, Code::Flags flags,
const char* name)
: raw_assembler_(new RawMachineAssembler(
isolate, new (zone) Graph(zone),
Linkage::GetJSCallDescriptor(zone, false, parameter_count,
CallDescriptor::kNoFlags))),
: CodeStubAssembler(isolate, zone, Linkage::GetJSCallDescriptor(
zone, false, parameter_count,
CallDescriptor::kNoFlags),
flags, name) {}
CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone,
CallDescriptor* call_descriptor,
Code::Flags flags, const char* name)
: raw_assembler_(new RawMachineAssembler(isolate, new (zone) Graph(zone),
call_descriptor)),
flags_(flags),
name_(name),
code_generated_(false),
......@@ -113,11 +116,18 @@ Node* CodeStubAssembler::HeapNumberMapConstant() {
return HeapConstant(isolate()->factory()->heap_number_map());
}
Node* CodeStubAssembler::NullConstant() {
return LoadRoot(Heap::kNullValueRootIndex);
}
Node* CodeStubAssembler::UndefinedConstant() {
return LoadRoot(Heap::kUndefinedValueRootIndex);
}
Node* CodeStubAssembler::Parameter(int value) {
return raw_assembler_->Parameter(value);
}
void CodeStubAssembler::Return(Node* value) {
return raw_assembler_->Return(value);
}
......@@ -211,13 +221,14 @@ Node* CodeStubAssembler::WordIsSmi(Node* a) {
IntPtrConstant(0));
}
Node* CodeStubAssembler::LoadBufferObject(Node* buffer, int offset) {
return raw_assembler_->Load(MachineType::AnyTagged(), buffer,
IntPtrConstant(offset));
Node* CodeStubAssembler::LoadBufferObject(Node* buffer, int offset,
MachineType rep) {
return raw_assembler_->Load(rep, buffer, IntPtrConstant(offset));
}
Node* CodeStubAssembler::LoadObjectField(Node* object, int offset) {
return raw_assembler_->Load(MachineType::AnyTagged(), object,
Node* CodeStubAssembler::LoadObjectField(Node* object, int offset,
MachineType rep) {
return raw_assembler_->Load(rep, object,
IntPtrConstant(offset - kHeapObjectTag));
}
......
......@@ -148,6 +148,8 @@ class CodeStubAssembler {
Node* Float64Constant(double value);
Node* BooleanMapConstant();
Node* HeapNumberMapConstant();
Node* NullConstant();
Node* UndefinedConstant();
Node* Parameter(int value);
void Return(Node* value);
......@@ -268,9 +270,11 @@ class CodeStubAssembler {
Node* WordIsSmi(Node* a);
// Load an object pointer from a buffer that isn't in the heap.
Node* LoadBufferObject(Node* buffer, int offset);
Node* LoadBufferObject(Node* buffer, int offset,
MachineType rep = MachineType::AnyTagged());
// Load a field from an object on the heap.
Node* LoadObjectField(Node* object, int offset);
Node* LoadObjectField(Node* object, int offset,
MachineType rep = MachineType::AnyTagged());
// Load the floating point value of a HeapNumber.
Node* LoadHeapNumberValue(Node* object);
// Load the bit field of a Map.
......@@ -338,6 +342,10 @@ class CodeStubAssembler {
private:
friend class CodeStubAssemblerTester;
CodeStubAssembler(Isolate* isolate, Zone* zone,
CallDescriptor* call_descriptor, Code::Flags flags,
const char* name);
Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args);
Node* TailCallN(CallDescriptor* descriptor, Node* code_target, Node** args);
......
......@@ -2,34 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/fast-accessor-assembler.h"
#include "src/fast-accessor-assembler.h"
#include "src/base/logging.h"
#include "src/code-stubs.h" // For CallApiCallbackStub.
#include "src/compiler/graph.h"
#include "src/compiler/linkage.h"
#include "src/compiler/pipeline.h"
#include "src/compiler/raw-machine-assembler.h"
#include "src/compiler/schedule.h"
#include "src/compiler/verifier.h"
#include "src/compiler/code-stub-assembler.h"
#include "src/handles-inl.h"
#include "src/objects.h" // For FAA::GetInternalField impl.
#include "src/objects.h" // For FAA::LoadInternalField impl.
using v8::internal::compiler::CodeStubAssembler;
using v8::internal::compiler::Node;
namespace v8 {
namespace internal {
namespace compiler {
FastAccessorAssembler::FastAccessorAssembler(Isolate* isolate)
: zone_(),
assembler_(new RawMachineAssembler(
isolate, new (zone()) Graph(zone()),
Linkage::GetJSCallDescriptor(&zone_, false, 1,
CallDescriptor::kNoFlags))),
isolate_(isolate),
assembler_(new CodeStubAssembler(isolate, zone(), 1,
Code::ComputeFlags(Code::STUB),
"FastAccessorAssembler")),
state_(kBuilding) {}
FastAccessorAssembler::~FastAccessorAssembler() {}
FastAccessorAssembler::~FastAccessorAssembler() { Clear(); }
FastAccessorAssembler::ValueId FastAccessorAssembler::IntegerConstant(
int const_value) {
......@@ -37,34 +32,32 @@ FastAccessorAssembler::ValueId FastAccessorAssembler::IntegerConstant(
return FromRaw(assembler_->NumberConstant(const_value));
}
FastAccessorAssembler::ValueId FastAccessorAssembler::GetReceiver() {
CHECK_EQ(kBuilding, state_);
// For JS call descriptor, the receiver is parameter 0. If we use other
// call descriptors, this may or may not hold. So let's check.
CHECK(assembler_->call_descriptor()->IsJSFunctionCall());
// For JS functions, the receiver is parameter 0.
return FromRaw(assembler_->Parameter(0));
}
FastAccessorAssembler::ValueId FastAccessorAssembler::LoadInternalField(
ValueId value, int field_no) {
CHECK_EQ(kBuilding, state_);
// Determine the 'value' object's instance type.
Node* object_map =
assembler_->Load(MachineType::Pointer(), FromId(value),
assembler_->IntPtrConstant(
Internals::kHeapObjectMapOffset - kHeapObjectTag));
Node* object_map = assembler_->LoadObjectField(
FromId(value), Internals::kHeapObjectMapOffset, MachineType::Pointer());
Node* instance_type = assembler_->WordAnd(
assembler_->Load(
MachineType::Uint16(), object_map,
assembler_->IntPtrConstant(
Internals::kMapInstanceTypeAndBitFieldOffset - kHeapObjectTag)),
assembler_->LoadObjectField(object_map,
Internals::kMapInstanceTypeAndBitFieldOffset,
MachineType::Uint16()),
assembler_->IntPtrConstant(0xff));
// Check whether we have a proper JSObject.
RawMachineLabel is_jsobject, is_not_jsobject, merge;
CodeStubAssembler::Variable result(assembler_.get(),
MachineRepresentation::kTagged);
CodeStubAssembler::Label is_jsobject(assembler_.get());
CodeStubAssembler::Label is_not_jsobject(assembler_.get());
CodeStubAssembler::Label merge(assembler_.get(), &result);
assembler_->Branch(
assembler_->WordEqual(
instance_type, assembler_->IntPtrConstant(Internals::kJSObjectType)),
......@@ -72,10 +65,10 @@ FastAccessorAssembler::ValueId FastAccessorAssembler::LoadInternalField(
// JSObject? Then load the internal field field_no.
assembler_->Bind(&is_jsobject);
Node* internal_field = assembler_->Load(
MachineType::Pointer(), FromId(value),
assembler_->IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag +
kPointerSize * field_no));
Node* internal_field = assembler_->LoadObjectField(
FromId(value), JSObject::kHeaderSize + kPointerSize * field_no,
MachineType::Pointer());
result.Bind(internal_field);
assembler_->Goto(&merge);
// No JSObject? Return undefined.
......@@ -83,43 +76,39 @@ FastAccessorAssembler::ValueId FastAccessorAssembler::LoadInternalField(
// the method should take a label instead.
assembler_->Bind(&is_not_jsobject);
Node* fail_value = assembler_->UndefinedConstant();
result.Bind(fail_value);
assembler_->Goto(&merge);
// Return.
assembler_->Bind(&merge);
Node* phi = assembler_->Phi(MachineRepresentation::kTagged, internal_field,
fail_value);
return FromRaw(phi);
return FromRaw(result.value());
}
FastAccessorAssembler::ValueId FastAccessorAssembler::LoadValue(ValueId value,
int offset) {
CHECK_EQ(kBuilding, state_);
return FromRaw(assembler_->Load(MachineType::IntPtr(), FromId(value),
assembler_->IntPtrConstant(offset)));
return FromRaw(assembler_->LoadBufferObject(FromId(value), offset,
MachineType::IntPtr()));
}
FastAccessorAssembler::ValueId FastAccessorAssembler::LoadObject(ValueId value,
int offset) {
CHECK_EQ(kBuilding, state_);
return FromRaw(
assembler_->Load(MachineType::AnyTagged(),
assembler_->Load(MachineType::Pointer(), FromId(value),
assembler_->IntPtrConstant(offset))));
return FromRaw(assembler_->LoadBufferObject(
assembler_->LoadBufferObject(FromId(value), offset,
MachineType::Pointer()),
0, MachineType::AnyTagged()));
}
void FastAccessorAssembler::ReturnValue(ValueId value) {
CHECK_EQ(kBuilding, state_);
assembler_->Return(FromId(value));
}
void FastAccessorAssembler::CheckFlagSetOrReturnNull(ValueId value, int mask) {
CHECK_EQ(kBuilding, state_);
RawMachineLabel pass, fail;
CodeStubAssembler::Label pass(assembler_.get());
CodeStubAssembler::Label fail(assembler_.get());
assembler_->Branch(
assembler_->Word32Equal(
assembler_->Word32And(FromId(value), assembler_->Int32Constant(mask)),
......@@ -130,39 +119,34 @@ void FastAccessorAssembler::CheckFlagSetOrReturnNull(ValueId value, int mask) {
assembler_->Bind(&pass);
}
void FastAccessorAssembler::CheckNotZeroOrReturnNull(ValueId value) {
CHECK_EQ(kBuilding, state_);
RawMachineLabel is_null, not_null;
CodeStubAssembler::Label is_null(assembler_.get());
CodeStubAssembler::Label not_null(assembler_.get());
assembler_->Branch(
assembler_->IntPtrEqual(FromId(value), assembler_->IntPtrConstant(0)),
assembler_->WordEqual(FromId(value), assembler_->IntPtrConstant(0)),
&is_null, &not_null);
assembler_->Bind(&is_null);
assembler_->Return(assembler_->NullConstant());
assembler_->Bind(&not_null);
}
FastAccessorAssembler::LabelId FastAccessorAssembler::MakeLabel() {
CHECK_EQ(kBuilding, state_);
RawMachineLabel* label =
new (zone()->New(sizeof(RawMachineLabel))) RawMachineLabel;
return FromRaw(label);
return FromRaw(new CodeStubAssembler::Label(assembler_.get()));
}
void FastAccessorAssembler::SetLabel(LabelId label_id) {
CHECK_EQ(kBuilding, state_);
assembler_->Bind(FromId(label_id));
}
void FastAccessorAssembler::CheckNotZeroOrJump(ValueId value_id,
LabelId label_id) {
CHECK_EQ(kBuilding, state_);
RawMachineLabel pass;
CodeStubAssembler::Label pass(assembler_.get());
assembler_->Branch(
assembler_->IntPtrEqual(FromId(value_id), assembler_->IntPtrConstant(0)),
assembler_->WordEqual(FromId(value_id), assembler_->IntPtrConstant(0)),
&pass, FromId(label_id));
assembler_->Bind(&pass);
}
......@@ -171,19 +155,25 @@ FastAccessorAssembler::ValueId FastAccessorAssembler::Call(
FunctionCallback callback_function, ValueId arg) {
CHECK_EQ(kBuilding, state_);
// Create API function stub.
CallApiCallbackStub stub(assembler_->isolate(), 1, true);
DCHECK_EQ(1, stub.GetCallInterfaceDescriptor().GetStackParameterCount());
// Wrap the FunctionCallback in an ExternalReference.
ApiFunction callback_api_function(FUNCTION_ADDR(callback_function));
ExternalReference callback(&callback_api_function,
ExternalReference::DIRECT_API_CALL,
assembler_->isolate());
ExternalReference::DIRECT_API_CALL, isolate());
// Create & call API callback via stub.
CallApiCallbackStub stub(isolate(), 1, true);
DCHECK_EQ(5, stub.GetCallInterfaceDescriptor().GetParameterCount());
DCHECK_EQ(1, stub.GetCallInterfaceDescriptor().GetStackParameterCount());
// TODO(vogelheim): There is currently no clean way to retrieve the context
// parameter for a stub and the implementation details are hidden in
// compiler/*. The context_paramter is computed as:
// Linkage::GetJSCallContextParamIndex(descriptor->JSParameterCount())
const int context_parameter = 2;
Node* call = assembler_->CallStub(
stub.GetCallInterfaceDescriptor(),
assembler_->HeapConstant(stub.GetCode()),
assembler_->Parameter(context_parameter),
// The stub has 6 parameters.
// See: ApiCallbackDescriptorBase::BuildCallInterfaceDescriptorFunctionType
Node* args[] = {
// Stub/register parameters:
assembler_->Parameter(0), /* receiver (use accessor's) */
assembler_->UndefinedConstant(), /* call_data (undefined) */
......@@ -191,70 +181,51 @@ FastAccessorAssembler::ValueId FastAccessorAssembler::Call(
assembler_->ExternalConstant(callback), /* API callback function */
// JS arguments, on stack:
FromId(arg),
// Context parameter. (See Linkage::GetStubCallDescriptor.)
assembler_->UndefinedConstant()};
DCHECK_EQ(arraysize(args),
1 + stub.GetCallInterfaceDescriptor().GetParameterCount());
Node* call = assembler_->CallN(
Linkage::GetStubCallDescriptor(
assembler_->isolate(), zone(), stub.GetCallInterfaceDescriptor(),
stub.GetStackParameterCount(), CallDescriptor::kNoFlags),
assembler_->HeapConstant(stub.GetCode()), args);
FromId(arg));
return FromRaw(call);
}
MaybeHandle<Code> FastAccessorAssembler::Build() {
CHECK_EQ(kBuilding, state_);
// Cleanup: We no longer need this.
nodes_.clear();
labels_.clear();
// Export the schedule and call the compiler.
Schedule* schedule = assembler_->Export();
Code::Flags flags = Code::ComputeFlags(Code::STUB);
MaybeHandle<Code> code = Pipeline::GenerateCodeForCodeStub(
assembler_->isolate(), assembler_->call_descriptor(), assembler_->graph(),
schedule, flags, "FastAccessorAssembler");
// Update state & return.
Handle<Code> code = assembler_->GenerateCode();
state_ = !code.is_null() ? kBuilt : kError;
Clear();
return code;
}
FastAccessorAssembler::ValueId FastAccessorAssembler::FromRaw(Node* node) {
nodes_.push_back(node);
ValueId value = {nodes_.size() - 1};
return value;
}
FastAccessorAssembler::LabelId FastAccessorAssembler::FromRaw(
RawMachineLabel* label) {
CodeStubAssembler::Label* label) {
labels_.push_back(label);
LabelId label_id = {labels_.size() - 1};
return label_id;
}
Node* FastAccessorAssembler::FromId(ValueId value) const {
CHECK_LT(value.value_id, nodes_.size());
CHECK_NOT_NULL(nodes_.at(value.value_id));
return nodes_.at(value.value_id);
}
RawMachineLabel* FastAccessorAssembler::FromId(LabelId label) const {
CodeStubAssembler::Label* FastAccessorAssembler::FromId(LabelId label) const {
CHECK_LT(label.label_id, labels_.size());
CHECK_NOT_NULL(labels_.at(label.label_id));
return labels_.at(label.label_id);
}
void FastAccessorAssembler::Clear() {
for (auto label : labels_) {
delete label;
}
nodes_.clear();
labels_.clear();
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -2,19 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_FAST_ACCESSOR_ASSEMBLER_H_
#define V8_COMPILER_FAST_ACCESSOR_ASSEMBLER_H_
#ifndef V8_FAST_ACCESSOR_ASSEMBLER_H_
#define V8_FAST_ACCESSOR_ASSEMBLER_H_
#include <stdint.h>
#include <vector>
// Clients of this interface shouldn't depend on lots of compiler internals.
// Do not include anything from src/compiler here!
#include "include/v8-experimental.h"
#include "src/base/macros.h"
#include "src/base/smart-pointers.h"
#include "src/handles.h"
// For CodeStubAssembler::Label. (We cannot forward-declare inner classes.)
#include "src/compiler/code-stub-assembler.h"
namespace v8 {
namespace internal {
......@@ -24,11 +24,8 @@ class Isolate;
class Zone;
namespace compiler {
class Node;
class RawMachineAssembler;
class RawMachineLabel;
}
// This interface "exports" an aggregated subset of RawMachineAssembler, for
// use by the API to implement Fast Dom Accessors.
......@@ -75,21 +72,24 @@ class FastAccessorAssembler {
MaybeHandle<Code> Build();
private:
ValueId FromRaw(Node* node);
LabelId FromRaw(RawMachineLabel* label);
Node* FromId(ValueId value) const;
RawMachineLabel* FromId(LabelId value) const;
ValueId FromRaw(compiler::Node* node);
LabelId FromRaw(compiler::CodeStubAssembler::Label* label);
compiler::Node* FromId(ValueId value) const;
compiler::CodeStubAssembler::Label* FromId(LabelId value) const;
void Clear();
Zone* zone() { return &zone_; }
Isolate* isolate() const { return isolate_; }
Zone zone_;
base::SmartPointer<RawMachineAssembler> assembler_;
Isolate* isolate_;
base::SmartPointer<compiler::CodeStubAssembler> assembler_;
// To prevent exposing the RMA internals to the outside world, we'll map
// Node + Label pointers integers wrapped in ValueId and LabelId instances.
// These vectors maintain this mapping.
std::vector<Node*> nodes_;
std::vector<RawMachineLabel*> labels_;
std::vector<compiler::Node*> nodes_;
std::vector<compiler::CodeStubAssembler::Label*> labels_;
// Remember the current state for easy error checking. (We prefer to be
// strict as this class will be exposed at the API.)
......@@ -98,8 +98,7 @@ class FastAccessorAssembler {
DISALLOW_COPY_AND_ASSIGN(FastAccessorAssembler);
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_FAST_ACCESSOR_ASSEMBLER_H_
#endif // V8_FAST_ACCESSOR_ASSEMBLER_H_
......@@ -586,8 +586,6 @@
'../../src/compiler/escape-analysis.h',
"../../src/compiler/escape-analysis-reducer.cc",
"../../src/compiler/escape-analysis-reducer.h",
'../../src/compiler/fast-accessor-assembler.cc',
'../../src/compiler/fast-accessor-assembler.h',
'../../src/compiler/frame.cc',
'../../src/compiler/frame.h',
'../../src/compiler/frame-elider.cc',
......@@ -851,6 +849,8 @@
'../../src/extensions/trigger-failure-extension.h',
'../../src/factory.cc',
'../../src/factory.h',
'../../src/fast-accessor-assembler.cc',
'../../src/fast-accessor-assembler.h',
'../../src/fast-dtoa.cc',
'../../src/fast-dtoa.h',
'../../src/field-index.h',
......
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