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 |