diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 241a01524d..4e43e35603 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -290,61 +290,6 @@ void HLoadKeyedGeneric::InternalSetOperandAt(int index, HValue* value) { } -void HCallKeyed::InternalSetOperandAt(int index, HValue* value) { - // The key and all the arguments are stored in the base class's arguments_ - // vector. The context is in the object itself. Ugly. - if (index <= argument_count()) { - arguments_[index] = value; - } else { - context_ = value; - } -} - - -void HCallNamed::InternalSetOperandAt(int index, HValue* value) { - // The arguments are in the base class's arguments_ vector. The context - // is in the object itself. - if (index < argument_count()) { - arguments_[index] = value; - } else { - context_ = value; - } -} - - -void HCallFunction::InternalSetOperandAt(int index, HValue* value) { - // The arguments are in the base class's arguments_ vector. The context - // is in the object itself. - if (index < argument_count()) { - arguments_[index] = value; - } else { - context_ = value; - } -} - - -void HCallGlobal::InternalSetOperandAt(int index, HValue* value) { - // The arguments are in the base class's arguments_ vector. The context - // is in the object itself. - if (index < argument_count()) { - arguments_[index] = value; - } else { - context_ = value; - } -} - - -void HCallNew::InternalSetOperandAt(int index, HValue* value) { - // The arguments are in the base class's arguments_ vector. The context - // is in the object itself. - if (index < argument_count()) { - arguments_[index] = value; - } else { - context_ = value; - } -} - - void HStoreKeyedGeneric::InternalSetOperandAt(int index, HValue* value) { if (index < 3) { operands_[index] = value; @@ -609,26 +554,64 @@ void HInstruction::Verify() { #endif -HCall::HCall(int count) : arguments_(Zone::NewArray(count), count) { - for (int i = 0; i < count; ++i) arguments_[i] = NULL; - set_representation(Representation::Tagged()); - SetAllSideEffects(); +void HCall::PrintDataTo(StringStream* stream) const { + stream->Add("#%d", argument_count()); } -void HCall::PrintDataTo(StringStream* stream) const { - stream->Add("("); - for (int i = 0; i < arguments_.length(); ++i) { - if (i != 0) stream->Add(", "); - arguments_.at(i)->PrintNameTo(stream); +void HUnaryCall::PrintDataTo(StringStream* stream) const { + value()->PrintNameTo(stream); + stream->Add(" "); + HCall::PrintDataTo(stream); +} + + +void HBinaryCall::PrintDataTo(StringStream* stream) const { + first()->PrintNameTo(stream); + stream->Add(" "); + second()->PrintNameTo(stream); + stream->Add(" "); + HCall::PrintDataTo(stream); +} + + +void HCallConstantFunction::PrintDataTo(StringStream* stream) const { + if (IsApplyFunction()) { + stream->Add("optimized apply "); + } else { + stream->Add("%o ", function()->shared()->DebugName()); } - stream->Add(")"); + HCall::PrintDataTo(stream); +} + + +void HCallNamed::PrintDataTo(StringStream* stream) const { + stream->Add("%o ", *name()); + HUnaryCall::PrintDataTo(stream); +} + + +void HCallGlobal::PrintDataTo(StringStream* stream) const { + stream->Add("%o ", *name()); + HUnaryCall::PrintDataTo(stream); +} + + +void HCallKnownGlobal::PrintDataTo(StringStream* stream) const { + stream->Add("o ", target()->shared()->DebugName()); + HCall::PrintDataTo(stream); +} + + +void HCallRuntime::PrintDataTo(StringStream* stream) const { + stream->Add("%o ", *name()); + HCall::PrintDataTo(stream); } void HClassOfTest::PrintDataTo(StringStream* stream) const { stream->Add("class_of_test("); - value()->PrintTo(stream); + value()->PrintNameTo(stream); stream->Add(", \"%o\")", *class_name()); } @@ -642,22 +625,6 @@ void HAccessArgumentsAt::PrintDataTo(StringStream* stream) const { } -void HCall::SetArgumentAt(int index, HPushArgument* push_argument) { - push_argument->set_argument_index(index); - SetOperandAt(index, push_argument); -} - - -void HCallConstantFunction::PrintDataTo(StringStream* stream) const { - if (IsApplyFunction()) { - stream->Add("SPECIAL function: apply"); - } else { - stream->Add("%s", *(function()->shared()->DebugName()->ToCString())); - } - HCall::PrintDataTo(stream); -} - - void HControlInstruction::PrintDataTo(StringStream* stream) const { if (FirstSuccessor() != NULL) { int first_id = FirstSuccessor()->block_id(); @@ -745,14 +712,6 @@ void HTypeofIs::PrintDataTo(StringStream* stream) const { } -void HPushArgument::PrintDataTo(StringStream* stream) const { - HUnaryOperation::PrintDataTo(stream); - if (argument_index() != -1) { - stream->Add(" [%d]", argument_index_); - } -} - - void HChange::PrintDataTo(StringStream* stream) const { HUnaryOperation::PrintDataTo(stream); stream->Add(" %s to %s", from_.Mnemonic(), to_.Mnemonic()); @@ -787,44 +746,10 @@ void HCheckFunction::PrintDataTo(StringStream* stream) const { } -void HCallKeyed::PrintDataTo(StringStream* stream) const { - stream->Add("["); - key()->PrintNameTo(stream); - stream->Add("]("); - for (int i = 1; i < arguments_.length(); ++i) { - if (i != 1) stream->Add(", "); - arguments_.at(i)->PrintNameTo(stream); - } - stream->Add(")"); -} - - -void HCallNamed::PrintDataTo(StringStream* stream) const { - SmartPointer name_string = name()->ToCString(); - stream->Add("%s ", *name_string); - HCall::PrintDataTo(stream); -} - - -void HCallGlobal::PrintDataTo(StringStream* stream) const { - SmartPointer name_string = name()->ToCString(); - stream->Add("%s ", *name_string); - HCall::PrintDataTo(stream); -} - - -void HCallRuntime::PrintDataTo(StringStream* stream) const { - SmartPointer name_string = name()->ToCString(); - stream->Add("%s ", *name_string); - HCall::PrintDataTo(stream); -} - - void HCallStub::PrintDataTo(StringStream* stream) const { - HUnaryOperation::PrintDataTo(stream); - stream->Add(" %s(%d)", - CodeStub::MajorName(major_key_, false), - argument_count_); + stream->Add("%s ", + CodeStub::MajorName(major_key_, false)); + HUnaryCall::PrintDataTo(stream); } diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index c65e8303ac..b9903c8d7e 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -48,6 +48,7 @@ class LChunkBuilder; #define HYDROGEN_ALL_INSTRUCTION_LIST(V) \ V(ArithmeticBinaryOperation) \ + V(BinaryCall) \ V(BinaryOperation) \ V(BitwiseBinaryOperation) \ V(Call) \ @@ -58,6 +59,7 @@ class LChunkBuilder; V(Phi) \ V(StoreKeyed) \ V(StoreNamed) \ + V(UnaryCall) \ V(UnaryControlInstruction) \ V(UnaryOperation) \ HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) @@ -1049,27 +1051,15 @@ class HLeaveInlined: public HInstruction { class HPushArgument: public HUnaryOperation { public: - explicit HPushArgument(HValue* value) - : HUnaryOperation(value), argument_index_(-1) { - set_representation(Representation::Tagged()); - } + explicit HPushArgument(HValue* value) : HUnaryOperation(value) { } virtual Representation RequiredInputRepresentation(int index) const { return Representation::Tagged(); } - virtual void PrintDataTo(StringStream* stream) const; HValue* argument() const { return OperandAt(0); } - int argument_index() const { return argument_index_; } - void set_argument_index(int index) { - ASSERT(argument_index_ == -1 || index == argument_index_); - argument_index_ = index; - } DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument") - - private: - int argument_index_; }; @@ -1132,36 +1122,80 @@ class HGlobalReceiver: public HUnaryOperation { class HCall: public HInstruction { public: - // Construct a call with uninitialized arguments. The argument count - // includes the receiver. - explicit HCall(int count); + // The argument count includes the receiver. + explicit HCall(int argument_count) : argument_count_(argument_count) { + set_representation(Representation::Tagged()); + SetAllSideEffects(); + } virtual HType CalculateInferredType() const { return HType::Tagged(); } - // TODO(3190496): This needs a cleanup. We don't want the arguments - // be operands of the call instruction. This results in bad code quality. - virtual int argument_count() const { return arguments_.length(); } - virtual int OperandCount() const { return argument_count(); } - virtual HValue* OperandAt(int index) const { return arguments_[index]; } - virtual HPushArgument* PushArgumentAt(int index) const { - return HPushArgument::cast(OperandAt(index)); - } - virtual HValue* ArgumentAt(int index) const { - return PushArgumentAt(index)->argument(); - } - virtual void SetArgumentAt(int index, HPushArgument* push_argument); + virtual int argument_count() const { return argument_count_; } virtual void PrintDataTo(StringStream* stream) const; DECLARE_INSTRUCTION(Call) - protected: - virtual void InternalSetOperandAt(int index, HValue* value) { - arguments_[index] = value; + private: + int argument_count_; +}; + + +class HUnaryCall: public HCall { + public: + HUnaryCall(HValue* value, int argument_count) + : HCall(argument_count), value_(NULL) { + SetOperandAt(0, value); } - int argument_count_; - Vector arguments_; + virtual void PrintDataTo(StringStream* stream) const; + + HValue* value() const { return value_; } + + virtual int OperandCount() const { return 1; } + virtual HValue* OperandAt(int index) const { + ASSERT(index == 0); + return value_; + } + + DECLARE_INSTRUCTION(UnaryCall) + + protected: + virtual void InternalSetOperandAt(int index, HValue* value) { + ASSERT(index == 0); + value_ = value; + } + + private: + HValue* value_; +}; + + +class HBinaryCall: public HCall { + public: + HBinaryCall(HValue* first, HValue* second, int argument_count) + : HCall(argument_count) { + SetOperandAt(0, first); + SetOperandAt(1, second); + } + + virtual void PrintDataTo(StringStream* stream) const; + + HValue* first() const { return operands_[0]; } + HValue* second() const { return operands_[1]; } + + virtual int OperandCount() const { return 2; } + virtual HValue* OperandAt(int index) const { return operands_[index]; } + + DECLARE_INSTRUCTION(BinaryCall) + + protected: + virtual void InternalSetOperandAt(int index, HValue* value) { + operands_[index] = value; + } + + private: + HOperandVector<2> operands_; }; @@ -1171,6 +1205,7 @@ class HCallConstantFunction: public HCall { : HCall(argument_count), function_(function) { } Handle function() const { return function_; } + bool IsApplyFunction() const { return function_->code() == Builtins::builtin(Builtins::FunctionApply); } @@ -1184,147 +1219,78 @@ class HCallConstantFunction: public HCall { }; -// TODO(3190496): This class uses hacks to get additional operands that ar -// not arguments to work with the current setup. This _needs_ a cleanup. -// (see HCall). -class HCallKeyed: public HCall { +class HCallKeyed: public HBinaryCall { public: HCallKeyed(HValue* context, HValue* key, int argument_count) - : HCall(argument_count + 1), context_(NULL) { - SetOperandAt(0, key); - SetOperandAt(argument_count + 1, context); + : HBinaryCall(context, key, argument_count) { } virtual Representation RequiredInputRepresentation(int index) const { return Representation::Tagged(); } - virtual void PrintDataTo(StringStream* stream) const; - - HValue* key() const { return OperandAt(0); } - HValue* context() const { return context_; } - - virtual int argument_count() const { return arguments_.length() - 1; } - virtual int OperandCount() const { return arguments_.length() + 1; } - - virtual HValue* OperandAt(int index) const { - // The key and all the arguments are stored in the base class's - // arguments_ vector. The context is in the object itself. Ugly. - return (index <= argument_count()) ? arguments_[index] : context_; - } - - virtual HPushArgument* PushArgumentAt(int index) const { - return HPushArgument::cast(OperandAt(index + 1)); - } - virtual void SetArgumentAt(int index, HPushArgument* push_argument) { - HCall::SetArgumentAt(index + 1, push_argument); - } + HValue* context() const { return first(); } + HValue* key() const { return second(); } DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed") - - protected: - virtual void InternalSetOperandAt(int index, HValue* value); - - private: - HValue* context_; }; -class HCallNamed: public HCall { +class HCallNamed: public HUnaryCall { public: HCallNamed(HValue* context, Handle name, int argument_count) - : HCall(argument_count), context_(NULL), name_(name) { - SetOperandAt(argument_count, context); + : HUnaryCall(context, argument_count), name_(name) { } virtual void PrintDataTo(StringStream* stream) const; - HValue* context() const { return context_; } + HValue* context() const { return value(); } Handle name() const { return name_; } - virtual int OperandCount() const { return arguments_.length() + 1; } - - virtual HValue* OperandAt(int index) const { - // The arguments are in the base class's arguments_ vector. The context - // is in the object itself. - return (index < argument_count()) ? arguments_[index] : context_; - } - DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named") - protected: - virtual void InternalSetOperandAt(int index, HValue* value); - private: - HValue* context_; Handle name_; }; -class HCallFunction: public HCall { +class HCallFunction: public HUnaryCall { public: HCallFunction(HValue* context, int argument_count) - : HCall(argument_count), context_(NULL) { - SetOperandAt(argument_count, context); + : HUnaryCall(context, argument_count) { } - HValue* context() const { return context_; } - - virtual int OperandCount() const { return arguments_.length() + 1; } - - virtual HValue* OperandAt(int index) const { - // The arguments are in the base class's arguments_ vector. The context - // is in the object itself. - return (index < argument_count()) ? arguments_[index] : context_; - } + HValue* context() const { return value(); } DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function") - - protected: - virtual void InternalSetOperandAt(int index, HValue* value); - - private: - HValue* context_; }; -class HCallGlobal: public HCall { +class HCallGlobal: public HUnaryCall { public: HCallGlobal(HValue* context, Handle name, int argument_count) - : HCall(argument_count), context_(NULL), name_(name) { - SetOperandAt(argument_count, context); + : HUnaryCall(context, argument_count), name_(name) { } virtual void PrintDataTo(StringStream* stream) const; - HValue* context() const { return context_; } + HValue* context() const { return value(); } Handle name() const { return name_; } - virtual int OperandCount() const { return arguments_.length() + 1; } - - virtual HValue* OperandAt(int index) const { - // The arguments are in the base class's arguments_ vector. The context - // is in the object itself. - return (index < argument_count()) ? arguments_[index] : context_; - } - DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global") - protected: - virtual void InternalSetOperandAt(int index, HValue* value); - private: - HValue* context_; Handle name_; }; class HCallKnownGlobal: public HCall { public: - HCallKnownGlobal(Handle target, - int argument_count) + HCallKnownGlobal(Handle target, int argument_count) : HCall(argument_count), target_(target) { } + virtual void PrintDataTo(StringStream* stream) const; + Handle target() const { return target_; } DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global") @@ -1334,35 +1300,20 @@ class HCallKnownGlobal: public HCall { }; -class HCallNew: public HCall { +class HCallNew: public HBinaryCall { public: - HCallNew(HValue* context, int argument_count) - : HCall(argument_count), context_(NULL) { - SetOperandAt(argument_count, context); + HCallNew(HValue* context, HValue* constructor, int argument_count) + : HBinaryCall(context, constructor, argument_count) { } virtual Representation RequiredInputRepresentation(int index) const { return Representation::Tagged(); } - HValue* context() const { return context_; } - HValue* constructor() const { return ArgumentAt(0); } - - virtual int OperandCount() const { return arguments_.length() + 1; } - - virtual HValue* OperandAt(int index) const { - // The arguments are in the base class's arguments_ vector. The context - // is in the object itself. - return (index < argument_count()) ? arguments_[index] : context_; - } + HValue* context() const { return first(); } + HValue* constructor() const { return second(); } DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new") - - protected: - virtual void InternalSetOperandAt(int index, HValue* value); - - private: - HValue* context_; }; @@ -2764,20 +2715,17 @@ class HParameter: public HInstruction { }; -class HCallStub: public HUnaryOperation { +class HCallStub: public HUnaryCall { public: HCallStub(HValue* context, CodeStub::Major major_key, int argument_count) - : HUnaryOperation(context), + : HUnaryCall(context, argument_count), major_key_(major_key), - argument_count_(argument_count), transcendental_type_(TranscendentalCache::kNumberOfCaches) { - set_representation(Representation::Tagged()); - SetAllSideEffects(); } CodeStub::Major major_key() { return major_key_; } - int argument_count() { return argument_count_; } - HValue* context() { return OperandAt(0); } + + HValue* context() const { return value(); } void set_transcendental_type(TranscendentalCache::Type transcendental_type) { transcendental_type_ = transcendental_type; @@ -2785,13 +2733,13 @@ class HCallStub: public HUnaryOperation { TranscendentalCache::Type transcendental_type() { return transcendental_type_; } + virtual void PrintDataTo(StringStream* stream) const; DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub") private: CodeStub::Major major_key_; - int argument_count_; TranscendentalCache::Type transcendental_type_; }; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index c341cd3aff..6b1cf35e66 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -2193,10 +2193,8 @@ void HGraphBuilder::VisitForControl(Expression* expr, } -HValue* HGraphBuilder::VisitArgument(Expression* expr) { +void HGraphBuilder::VisitArgument(Expression* expr) { VisitForValue(expr); - if (HasStackOverflow() || !subgraph()->HasExit()) return NULL; - return environment()->Top(); } @@ -2315,29 +2313,15 @@ void HGraphBuilder::PushAndAdd(HInstruction* instr) { } -void HGraphBuilder::PushArgumentsForStubCall(int argument_count) { - const int kMaxStubArguments = 4; - ASSERT_GE(kMaxStubArguments, argument_count); - // Push the arguments on the stack. - HValue* arguments[kMaxStubArguments]; - for (int i = argument_count - 1; i >= 0; i--) { - arguments[i] = Pop(); - } - for (int i = 0; i < argument_count; i++) { - AddInstruction(new HPushArgument(arguments[i])); - } -} - - -void HGraphBuilder::ProcessCall(HCall* call) { - for (int i = call->argument_count() - 1; i >= 0; --i) { - HValue* value = Pop(); - HPushArgument* push = new HPushArgument(value); - call->SetArgumentAt(i, push); +void HGraphBuilder::PreProcessCall(HCall* call) { + int count = call->argument_count(); + ZoneList arguments(count); + for (int i = 0; i < count; ++i) { + arguments.Add(Pop()); } - for (int i = 0; i < call->argument_count(); ++i) { - AddInstruction(call->PushArgumentAt(i)); + while (!arguments.is_empty()) { + AddInstruction(new HPushArgument(arguments.RemoveLast())); } } @@ -3945,7 +3929,7 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, CHECK_BAILOUT; HCall* call = new HCallConstantFunction(expr->target(), argument_count); call->set_position(expr->position()); - ProcessCall(call); + PreProcessCall(call); PushAndAdd(call); } subgraphs.Add(subgraph); @@ -3961,7 +3945,7 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, AddInstruction(context); HCall* call = new HCallNamed(context, name, argument_count); call->set_position(expr->position()); - ProcessCall(call); + PreProcessCall(call); ast_context()->ReturnInstruction(call, expr->id()); } else { // Build subgraph for generic call through IC. @@ -3975,7 +3959,7 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, AddInstruction(context); HCall* call = new HCallNamed(context, name, argument_count); call->set_position(expr->position()); - ProcessCall(call); + PreProcessCall(call); PushAndAdd(call); } subgraphs.Add(subgraph); @@ -4397,7 +4381,7 @@ void HGraphBuilder::VisitCall(Call* expr) { AddInstruction(context); call = new HCallKeyed(context, key, argument_count); call->set_position(expr->position()); - ProcessCall(call); + PreProcessCall(call); Drop(1); // Key. ast_context()->ReturnInstruction(call, expr->id()); return; @@ -4409,7 +4393,7 @@ void HGraphBuilder::VisitCall(Call* expr) { if (TryCallApply(expr)) return; CHECK_BAILOUT; - HValue* receiver = VisitArgument(prop->obj()); + VisitArgument(prop->obj()); CHECK_BAILOUT; VisitArgumentList(expr->arguments()); CHECK_BAILOUT; @@ -4419,6 +4403,8 @@ void HGraphBuilder::VisitCall(Call* expr) { expr->RecordTypeFeedback(oracle()); ZoneMapList* types = expr->GetReceiverTypes(); + HValue* receiver = + environment()->ExpressionStackAt(expr->arguments()->length()); if (expr->IsMonomorphic()) { Handle receiver_map = (types == NULL) ? Handle::null() : types->first(); @@ -4554,7 +4540,7 @@ void HGraphBuilder::VisitCall(Call* expr) { } call->set_position(expr->position()); - ProcessCall(call); + PreProcessCall(call); ast_context()->ReturnInstruction(call, expr->id()); } @@ -4567,12 +4553,16 @@ void HGraphBuilder::VisitCallNew(CallNew* expr) { VisitArgumentList(expr->arguments()); CHECK_BAILOUT; - int argument_count = expr->arguments()->length() + 1; // Plus constructor. HContext* context = new HContext; AddInstruction(context); - HCall* call = new HCallNew(context, argument_count); + + // The constructor is both an operand to the instruction and an argument + // to the construct call. + int arg_count = expr->arguments()->length() + 1; // Plus constructor. + HValue* constructor = environment()->ExpressionStackAt(arg_count - 1); + HCall* call = new HCallNew(context, constructor, arg_count); call->set_position(expr->position()); - ProcessCall(call); + PreProcessCall(call); ast_context()->ReturnInstruction(call, expr->id()); } @@ -4626,7 +4616,7 @@ void HGraphBuilder::VisitCallRuntime(CallRuntime* expr) { ASSERT(function->intrinsic_type == Runtime::RUNTIME); HCall* call = new HCallRuntime(name, expr->function(), argument_count); call->set_position(RelocInfo::kNoPosition); - ProcessCall(call); + PreProcessCall(call); ast_context()->ReturnInstruction(call, expr->id()); } } @@ -5313,11 +5303,11 @@ void HGraphBuilder::GenerateStringCharFromCode(int argument_count, // Fast support for string.charAt(n) and string[n]. void HGraphBuilder::GenerateStringCharAt(int argument_count, int ast_id) { ASSERT_EQ(2, argument_count); - PushArgumentsForStubCall(argument_count); HContext* context = new HContext; AddInstruction(context); HCallStub* result = new HCallStub(context, CodeStub::StringCharAt, argument_count); + PreProcessCall(result); ast_context()->ReturnInstruction(result, ast_id); } @@ -5346,11 +5336,11 @@ void HGraphBuilder::GenerateRandomHeapNumber(int argument_count, int ast_id) { // Fast support for StringAdd. void HGraphBuilder::GenerateStringAdd(int argument_count, int ast_id) { ASSERT_EQ(2, argument_count); - PushArgumentsForStubCall(argument_count); HContext* context = new HContext; AddInstruction(context); HCallStub* result = new HCallStub(context, CodeStub::StringAdd, argument_count); + PreProcessCall(result); ast_context()->ReturnInstruction(result, ast_id); } @@ -5358,11 +5348,11 @@ void HGraphBuilder::GenerateStringAdd(int argument_count, int ast_id) { // Fast support for SubString. void HGraphBuilder::GenerateSubString(int argument_count, int ast_id) { ASSERT_EQ(3, argument_count); - PushArgumentsForStubCall(argument_count); HContext* context = new HContext; AddInstruction(context); HCallStub* result = new HCallStub(context, CodeStub::SubString, argument_count); + PreProcessCall(result); ast_context()->ReturnInstruction(result, ast_id); } @@ -5370,11 +5360,11 @@ void HGraphBuilder::GenerateSubString(int argument_count, int ast_id) { // Fast support for StringCompare. void HGraphBuilder::GenerateStringCompare(int argument_count, int ast_id) { ASSERT_EQ(2, argument_count); - PushArgumentsForStubCall(argument_count); HContext* context = new HContext; AddInstruction(context); HCallStub* result = new HCallStub(context, CodeStub::StringCompare, argument_count); + PreProcessCall(result); ast_context()->ReturnInstruction(result, ast_id); } @@ -5382,11 +5372,11 @@ void HGraphBuilder::GenerateStringCompare(int argument_count, int ast_id) { // Support for direct calls from JavaScript to native RegExp code. void HGraphBuilder::GenerateRegExpExec(int argument_count, int ast_id) { ASSERT_EQ(4, argument_count); - PushArgumentsForStubCall(argument_count); HContext* context = new HContext; AddInstruction(context); HCallStub* result = new HCallStub(context, CodeStub::RegExpExec, argument_count); + PreProcessCall(result); ast_context()->ReturnInstruction(result, ast_id); } @@ -5395,11 +5385,11 @@ void HGraphBuilder::GenerateRegExpExec(int argument_count, int ast_id) { void HGraphBuilder::GenerateRegExpConstructResult(int argument_count, int ast_id) { ASSERT_EQ(3, argument_count); - PushArgumentsForStubCall(argument_count); HContext* context = new HContext; AddInstruction(context); HCallStub* result = new HCallStub(context, CodeStub::RegExpConstructResult, argument_count); + PreProcessCall(result); ast_context()->ReturnInstruction(result, ast_id); } @@ -5413,11 +5403,11 @@ void HGraphBuilder::GenerateGetFromCache(int argument_count, int ast_id) { // Fast support for number to string. void HGraphBuilder::GenerateNumberToString(int argument_count, int ast_id) { ASSERT_EQ(1, argument_count); - PushArgumentsForStubCall(argument_count); HContext* context = new HContext; AddInstruction(context); HCallStub* result = new HCallStub(context, CodeStub::NumberToString, argument_count); + PreProcessCall(result); ast_context()->ReturnInstruction(result, ast_id); } @@ -5448,36 +5438,36 @@ void HGraphBuilder::GenerateMathPow(int argument_count, int ast_id) { void HGraphBuilder::GenerateMathSin(int argument_count, int ast_id) { ASSERT_EQ(1, argument_count); - PushArgumentsForStubCall(argument_count); HContext* context = new HContext; AddInstruction(context); HCallStub* result = new HCallStub(context, CodeStub::TranscendentalCache, argument_count); result->set_transcendental_type(TranscendentalCache::SIN); + PreProcessCall(result); ast_context()->ReturnInstruction(result, ast_id); } void HGraphBuilder::GenerateMathCos(int argument_count, int ast_id) { ASSERT_EQ(1, argument_count); - PushArgumentsForStubCall(argument_count); HContext* context = new HContext; AddInstruction(context); HCallStub* result = new HCallStub(context, CodeStub::TranscendentalCache, argument_count); result->set_transcendental_type(TranscendentalCache::COS); + PreProcessCall(result); ast_context()->ReturnInstruction(result, ast_id); } void HGraphBuilder::GenerateMathLog(int argument_count, int ast_id) { ASSERT_EQ(1, argument_count); - PushArgumentsForStubCall(argument_count); HContext* context = new HContext; AddInstruction(context); HCallStub* result = new HCallStub(context, CodeStub::TranscendentalCache, argument_count); result->set_transcendental_type(TranscendentalCache::LOG); + PreProcessCall(result); ast_context()->ReturnInstruction(result, ast_id); } diff --git a/src/hydrogen.h b/src/hydrogen.h index 9d0cddf145..7cf80ab3e3 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -706,19 +706,17 @@ class HGraphBuilder: public AstVisitor { HBasicBlock* true_block, HBasicBlock* false_block); - // Visit an argument and wrap it in a PushArgument instruction. - HValue* VisitArgument(Expression* expr); + // Visit an argument subexpression. + void VisitArgument(Expression* expr); void VisitArgumentList(ZoneList* arguments); void AddPhi(HPhi* phi); void PushAndAdd(HInstruction* instr); - void PushArgumentsForStubCall(int argument_count); - // Remove the arguments from the bailout environment and emit instructions // to push them as outgoing parameters. - void ProcessCall(HCall* call); + void PreProcessCall(HCall* call); void AssumeRepresentation(HValue* value, Representation r); static Representation ToRepresentation(TypeInfo info);