| Index: src/fast-accessor-assembler.cc
|
| diff --git a/src/compiler/fast-accessor-assembler.cc b/src/fast-accessor-assembler.cc
|
| similarity index 58%
|
| rename from src/compiler/fast-accessor-assembler.cc
|
| rename to src/fast-accessor-assembler.cc
|
| index 1a97fd5337e6cc6aa9af729cb94a3bdb1f056b8e..0e1d48bb7c48123b20ae4052b9509fb64a342f14 100644
|
| --- a/src/compiler/fast-accessor-assembler.cc
|
| +++ b/src/fast-accessor-assembler.cc
|
| @@ -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, ¬_null);
|
| assembler_->Bind(&is_null);
|
| assembler_->Return(assembler_->NullConstant());
|
| assembler_->Bind(¬_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
|
|
|