Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index c3dfd5ff261db65fa7ad2c1d148253ed4baa9967..c9d8e7b69e00b40e19d7b9c913a10808aa6d8ae4 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<HValue*> 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<Map> receiver_map = |
(types == NULL) ? Handle<Map>::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()); |
} |
} |
@@ -5307,11 +5297,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); |
} |
@@ -5340,11 +5330,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); |
} |
@@ -5352,11 +5342,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); |
} |
@@ -5364,11 +5354,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); |
} |
@@ -5376,11 +5366,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); |
} |
@@ -5389,11 +5379,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); |
} |
@@ -5407,11 +5397,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); |
} |
@@ -5442,36 +5432,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); |
} |