}
+void AllocateHeapNumberDescriptor::Initialize(
+ CallInterfaceDescriptorData* data) {
+ // register state
+ // cp -- context
+ Register registers[] = {cp};
+ data->Initialize(arraysize(registers), registers, nullptr);
+}
+
+
void ArrayConstructorConstantArgCountDescriptor::Initialize(
CallInterfaceDescriptorData* data) {
// register state
}
+void AllocateHeapNumberDescriptor::Initialize(
+ CallInterfaceDescriptorData* data) {
+ // cp: context
+ Register registers[] = {cp};
+ data->Initialize(arraysize(registers), registers, nullptr);
+}
+
+
void ArrayConstructorConstantArgCountDescriptor::Initialize(
CallInterfaceDescriptorData* data) {
// cp: context
// static
+Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) {
+ AllocateHeapNumberStub stub(isolate);
+ return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
+}
+
+
+// static
Callable CodeFactory::CallFunction(Isolate* isolate, int argc,
CallFunctionFlags flags) {
CallFunctionStub stub(isolate, argc, flags);
static Callable StringAdd(Isolate* isolate, StringAddFlags flags,
PretenureFlag pretenure_flag);
+ static Callable AllocateHeapNumber(Isolate* isolate);
+
static Callable CallFunction(Isolate* isolate, int argc,
CallFunctionFlags flags);
};
-}
-}
+
+} // namespace internal
+} // namespace v8
+
#endif // V8_CODE_FACTORY_H_
return DoGenerateCode(this);
}
+
+template <>
+HValue* CodeStubGraphBuilder<AllocateHeapNumberStub>::BuildCodeStub() {
+ HValue* result =
+ Add<HAllocate>(Add<HConstant>(HeapNumber::kSize), HType::HeapNumber(),
+ NOT_TENURED, HEAP_NUMBER_TYPE);
+ AddStoreMapConstant(result, isolate()->factory()->heap_number_map());
+ return result;
+}
+
+
+Handle<Code> AllocateHeapNumberStub::GenerateCode() {
+ return DoGenerateCode(this);
+}
+
+
HValue* CodeStubGraphBuilderBase::BuildArrayConstructor(
ElementsKind kind,
AllocationSiteOverrideMode override_mode,
}
+void AllocateHeapNumberStub::InitializeDescriptor(
+ CodeStubDescriptor* descriptor) {
+ descriptor->Initialize(
+ Runtime::FunctionForId(Runtime::kAllocateHeapNumber)->entry);
+}
+
+
void CompareNilICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
descriptor->Initialize(FUNCTION_ADDR(CompareNilIC_Miss));
descriptor->SetMissHandler(
V(StubFailureTrampoline) \
V(SubString) \
/* HydrogenCodeStubs */ \
+ V(AllocateHeapNumber) \
V(ArrayNArgumentsConstructor) \
V(ArrayNoArgumentConstructor) \
V(ArraySingleArgumentConstructor) \
};
+class AllocateHeapNumberStub FINAL : public HydrogenCodeStub {
+ public:
+ explicit AllocateHeapNumberStub(Isolate* isolate)
+ : HydrogenCodeStub(isolate) {}
+
+ private:
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateHeapNumber);
+ DEFINE_HYDROGEN_CODE_STUB(AllocateHeapNumber, HydrogenCodeStub);
+};
+
+
class ArrayConstructorStubBase : public HydrogenCodeStub {
public:
ArrayConstructorStubBase(Isolate* isolate,
#include "src/compiler/change-lowering.h"
+#include "src/code-factory.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/linkage.h"
#include "src/compiler/machine-operator.h"
Node* ChangeLowering::AllocateHeapNumberWithValue(Node* value, Node* control) {
- // The AllocateHeapNumber() runtime function does not use the context, so we
- // can safely pass in Smi zero here.
+ // The AllocateHeapNumberStub does not use the context, so we can safely pass
+ // in Smi zero here.
+ Callable callable = CodeFactory::AllocateHeapNumber(isolate());
+ CallDescriptor* descriptor = linkage()->GetStubCallDescriptor(
+ callable.descriptor(), 0, CallDescriptor::kNoFlags);
+ Node* target = jsgraph()->HeapConstant(callable.code());
Node* context = jsgraph()->ZeroConstant();
Node* effect = graph()->NewNode(common()->ValueEffect(1), value);
- const Runtime::Function* function =
- Runtime::FunctionForId(Runtime::kAllocateHeapNumber);
- DCHECK_EQ(0, function->nargs);
- CallDescriptor* desc = linkage()->GetRuntimeCallDescriptor(
- function->function_id, 0, Operator::kNoProperties);
- Node* heap_number = graph()->NewNode(
- common()->Call(desc), jsgraph()->CEntryStubConstant(),
- jsgraph()->ExternalConstant(ExternalReference(function, isolate())),
- jsgraph()->Int32Constant(function->nargs), context, effect, control);
+ Node* heap_number = graph()->NewNode(common()->Call(descriptor), target,
+ context, effect, control);
Node* store = graph()->NewNode(
machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)),
heap_number, HeapNumberValueIndexConstant(), value, heap_number, control);
}
+void AllocateHeapNumberDescriptor::Initialize(
+ CallInterfaceDescriptorData* data) {
+ // register state
+ // esi -- context
+ Register registers[] = {esi};
+ data->Initialize(arraysize(registers), registers, nullptr);
+}
+
+
void ArrayConstructorConstantArgCountDescriptor::Initialize(
CallInterfaceDescriptorData* data) {
// register state
V(CallConstruct) \
V(RegExpConstructResult) \
V(TransitionElementsKind) \
+ V(AllocateHeapNumber) \
V(ArrayConstructorConstantArgCount) \
V(ArrayConstructor) \
V(InternalArrayConstructorConstantArgCount) \
};
+class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor {
+ public:
+ DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor)
+};
+
+
class ArrayConstructorConstantArgCountDescriptor
: public CallInterfaceDescriptor {
public:
}
+void AllocateHeapNumberDescriptor::Initialize(
+ CallInterfaceDescriptorData* data) {
+ // register state
+ // rsi -- context
+ Register registers[] = {rsi};
+ data->Initialize(arraysize(registers), registers, nullptr);
+}
+
+
void ArrayConstructorConstantArgCountDescriptor::Initialize(
CallInterfaceDescriptorData* data) {
// register state
Matcher<Node*> IsAllocateHeapNumber(const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher) {
- return IsCall(
- _, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
- CEntryStub(isolate(), 1).GetCode())),
- IsExternalConstant(ExternalReference(
- Runtime::FunctionForId(Runtime::kAllocateHeapNumber), isolate())),
- IsInt32Constant(0), IsNumberConstant(0.0), effect_matcher,
- control_matcher);
+ return IsCall(_, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
+ AllocateHeapNumberStub(isolate()).GetCode())),
+ IsNumberConstant(0.0), effect_matcher, control_matcher);
}
Matcher<Node*> IsLoadHeapNumber(const Matcher<Node*>& value_matcher,
const Matcher<Node*>& control_matcher) {
};
-class IsCallMatcher FINAL : public NodeMatcher {
+class IsCall2Matcher FINAL : public NodeMatcher {
public:
- IsCallMatcher(const Matcher<CallDescriptor*>& descriptor_matcher,
- const Matcher<Node*>& value0_matcher,
- const Matcher<Node*>& value1_matcher,
- const Matcher<Node*>& value2_matcher,
- const Matcher<Node*>& value3_matcher,
- const Matcher<Node*>& effect_matcher,
- const Matcher<Node*>& control_matcher)
+ IsCall2Matcher(const Matcher<CallDescriptor*>& descriptor_matcher,
+ const Matcher<Node*>& value0_matcher,
+ const Matcher<Node*>& value1_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher)
+ : NodeMatcher(IrOpcode::kCall),
+ descriptor_matcher_(descriptor_matcher),
+ value0_matcher_(value0_matcher),
+ value1_matcher_(value1_matcher),
+ effect_matcher_(effect_matcher),
+ control_matcher_(control_matcher) {}
+
+ virtual void DescribeTo(std::ostream* os) const OVERRIDE {
+ NodeMatcher::DescribeTo(os);
+ *os << " whose value0 (";
+ value0_matcher_.DescribeTo(os);
+ *os << ") and value1 (";
+ value1_matcher_.DescribeTo(os);
+ *os << ") and effect (";
+ effect_matcher_.DescribeTo(os);
+ *os << ") and control (";
+ control_matcher_.DescribeTo(os);
+ *os << ")";
+ }
+
+ virtual bool MatchAndExplain(Node* node,
+ MatchResultListener* listener) const OVERRIDE {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(OpParameter<CallDescriptor*>(node),
+ "descriptor", descriptor_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+ "value0", value0_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+ "value1", value1_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+ effect_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+ "control", control_matcher_, listener));
+ }
+
+ private:
+ const Matcher<CallDescriptor*> descriptor_matcher_;
+ const Matcher<Node*> value0_matcher_;
+ const Matcher<Node*> value1_matcher_;
+ const Matcher<Node*> effect_matcher_;
+ const Matcher<Node*> control_matcher_;
+};
+
+
+class IsCall4Matcher FINAL : public NodeMatcher {
+ public:
+ IsCall4Matcher(const Matcher<CallDescriptor*>& descriptor_matcher,
+ const Matcher<Node*>& value0_matcher,
+ const Matcher<Node*>& value1_matcher,
+ const Matcher<Node*>& value2_matcher,
+ const Matcher<Node*>& value3_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher)
: NodeMatcher(IrOpcode::kCall),
descriptor_matcher_(descriptor_matcher),
value0_matcher_(value0_matcher),
Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
const Matcher<Node*>& value0_matcher,
const Matcher<Node*>& value1_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher) {
+ return MakeMatcher(new IsCall2Matcher(descriptor_matcher, value0_matcher,
+ value1_matcher, effect_matcher,
+ control_matcher));
+}
+
+
+Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
+ const Matcher<Node*>& value0_matcher,
+ const Matcher<Node*>& value1_matcher,
const Matcher<Node*>& value2_matcher,
const Matcher<Node*>& value3_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher) {
- return MakeMatcher(new IsCallMatcher(
+ return MakeMatcher(new IsCall4Matcher(
descriptor_matcher, value0_matcher, value1_matcher, value2_matcher,
value3_matcher, effect_matcher, control_matcher));
}
Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
const Matcher<Node*>& value0_matcher,
const Matcher<Node*>& value1_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
+ const Matcher<Node*>& value0_matcher,
+ const Matcher<Node*>& value1_matcher,
const Matcher<Node*>& value2_matcher,
const Matcher<Node*>& value3_matcher,
const Matcher<Node*>& effect_matcher,