Revert last revert.

TBR=whesse@chromium.org
Review URL: http://codereview.chromium.org/8286023

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9635 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 85ab75df
...@@ -4539,9 +4539,9 @@ bool HGraphBuilder::TryInline(Call* expr) { ...@@ -4539,9 +4539,9 @@ bool HGraphBuilder::TryInline(Call* expr) {
return false; return false;
} }
CompilationInfo* outer_info = info();
#if !defined(V8_TARGET_ARCH_IA32) #if !defined(V8_TARGET_ARCH_IA32)
// Target must be able to use caller's context. // Target must be able to use caller's context.
CompilationInfo* outer_info = info();
if (target->context() != outer_info->closure()->context() || if (target->context() != outer_info->closure()->context() ||
outer_info->scope()->contains_with() || outer_info->scope()->contains_with() ||
outer_info->scope()->num_heap_slots() > 0) { outer_info->scope()->num_heap_slots() > 0) {
...@@ -4564,9 +4564,13 @@ bool HGraphBuilder::TryInline(Call* expr) { ...@@ -4564,9 +4564,13 @@ bool HGraphBuilder::TryInline(Call* expr) {
} }
// Don't inline recursive functions. // Don't inline recursive functions.
if (*target_shared == outer_info->closure()->shared()) { for (FunctionState* state = function_state();
TraceInline(target, caller, "target is recursive"); state != NULL;
return false; state = state->outer()) {
if (state->compilation_info()->closure()->shared() == *target_shared) {
TraceInline(target, caller, "target is recursive");
return false;
}
} }
// We don't want to add more than a certain number of nodes from inlining. // We don't want to add more than a certain number of nodes from inlining.
...@@ -5071,18 +5075,25 @@ void HGraphBuilder::VisitCall(Call* expr) { ...@@ -5071,18 +5075,25 @@ void HGraphBuilder::VisitCall(Call* expr) {
// The function is lingering in the deoptimization environment. // The function is lingering in the deoptimization environment.
// Handle it by case analysis on the AST context. // Handle it by case analysis on the AST context.
if (ast_context()->IsEffect()) { if (ast_context()->IsEffect()) {
if (current_block() == NULL) return;
ASSERT(Top() == function);
Drop(1); Drop(1);
} else if (ast_context()->IsValue()) { } else if (ast_context()->IsValue()) {
if (current_block() == NULL) return;
HValue* result = Pop(); HValue* result = Pop();
ASSERT(Top() == function);
Drop(1); Drop(1);
Push(result); Push(result);
} else if (ast_context()->IsTest()) { } else if (ast_context()->IsTest()) {
ASSERT(current_block() == NULL);
TestContext* context = TestContext::cast(ast_context()); TestContext* context = TestContext::cast(ast_context());
if (context->if_true()->HasPredecessor()) { if (context->if_true()->HasPredecessor() &&
context->if_true()->last_environment()->Top() == function) {
context->if_true()->last_environment()->Drop(1); context->if_true()->last_environment()->Drop(1);
} }
if (context->if_false()->HasPredecessor()) { if (context->if_false()->HasPredecessor() &&
context->if_true()->last_environment()->Drop(1); context->if_false()->last_environment()->Top() == function) {
context->if_false()->last_environment()->Drop(1);
} }
} else { } else {
UNREACHABLE(); UNREACHABLE();
...@@ -5302,7 +5313,6 @@ void HGraphBuilder::VisitBitNot(UnaryOperation* expr) { ...@@ -5302,7 +5313,6 @@ void HGraphBuilder::VisitBitNot(UnaryOperation* expr) {
void HGraphBuilder::VisitNot(UnaryOperation* expr) { void HGraphBuilder::VisitNot(UnaryOperation* expr) {
// TODO(svenpanne) Perhaps a switch/virtual function is nicer here.
if (ast_context()->IsTest()) { if (ast_context()->IsTest()) {
TestContext* context = TestContext::cast(ast_context()); TestContext* context = TestContext::cast(ast_context());
VisitForControl(expr->expression(), VisitForControl(expr->expression(),
......
...@@ -2104,7 +2104,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { ...@@ -2104,7 +2104,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
} }
CallFunctionStub stub(arg_count, flags); CallFunctionStub stub(arg_count, flags);
__ CallStub(&stub); __ CallStub(&stub, expr->id());
if (record_call_target) { if (record_call_target) {
// There is a one element cache in the instruction stream. // There is a one element cache in the instruction stream.
#ifdef DEBUG #ifdef DEBUG
......
...@@ -5196,7 +5196,7 @@ bool ParserApi::Parse(CompilationInfo* info) { ...@@ -5196,7 +5196,7 @@ bool ParserApi::Parse(CompilationInfo* info) {
Handle<Script> script = info->script(); Handle<Script> script = info->script();
bool harmony_scoping = !info->is_native() && FLAG_harmony_scoping; bool harmony_scoping = !info->is_native() && FLAG_harmony_scoping;
if (info->is_lazy()) { if (info->is_lazy()) {
Parser parser(script, info->isolate()->bootstrapper()->IsActive() || info->allows_natives_syntax(), NULL, NULL); Parser parser(script, true, NULL, NULL);
parser.SetHarmonyScoping(harmony_scoping); parser.SetHarmonyScoping(harmony_scoping);
result = parser.ParseLazy(info); result = parser.ParseLazy(info);
} else { } else {
......
...@@ -496,61 +496,56 @@ void TypeFeedbackOracle::RelocateRelocInfos(ZoneList<RelocInfo>* infos, ...@@ -496,61 +496,56 @@ void TypeFeedbackOracle::RelocateRelocInfos(ZoneList<RelocInfo>* infos,
void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) { void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
for (int i = 0; i < infos->length(); i++) { for (int i = 0; i < infos->length(); i++) {
Address target_address = (*infos)[i].target_address(); RelocInfo reloc_entry = (*infos)[i];
Address target_address = reloc_entry.target_address();
unsigned ast_id = static_cast<unsigned>((*infos)[i].data()); unsigned ast_id = static_cast<unsigned>((*infos)[i].data());
ProcessTargetAt(target_address, ast_id); Code* target = Code::GetCodeFromTargetAddress(target_address);
} switch (target->kind()) {
} case Code::LOAD_IC:
case Code::STORE_IC:
case Code::CALL_IC:
case Code::KEYED_CALL_IC:
if (target->ic_state() == MONOMORPHIC) {
if (target->kind() == Code::CALL_IC &&
target->check_type() != RECEIVER_MAP_CHECK) {
SetInfo(ast_id, Smi::FromInt(target->check_type()));
} else {
Object* map = target->FindFirstMap();
SetInfo(ast_id, map == NULL ? static_cast<Object*>(target) : map);
}
} else if (target->ic_state() == MEGAMORPHIC) {
SetInfo(ast_id, target);
}
break;
void TypeFeedbackOracle::ProcessTargetAt(Address target_address, case Code::KEYED_LOAD_IC:
unsigned ast_id) { case Code::KEYED_STORE_IC:
Code* target = Code::GetCodeFromTargetAddress(target_address); if (target->ic_state() == MONOMORPHIC ||
switch (target->kind()) { target->ic_state() == MEGAMORPHIC) {
case Code::LOAD_IC: SetInfo(ast_id, target);
case Code::STORE_IC:
case Code::CALL_IC:
case Code::KEYED_CALL_IC:
if (target->ic_state() == MONOMORPHIC) {
if (target->kind() == Code::CALL_IC &&
target->check_type() != RECEIVER_MAP_CHECK) {
SetInfo(ast_id, Smi::FromInt(target->check_type()));
} else {
Object* map = target->FindFirstMap();
SetInfo(ast_id, map == NULL ? static_cast<Object*>(target) : map);
} }
} else if (target->ic_state() == MEGAMORPHIC) { break;
SetInfo(ast_id, target);
}
break;
case Code::KEYED_LOAD_IC: case Code::UNARY_OP_IC:
case Code::KEYED_STORE_IC: case Code::BINARY_OP_IC:
if (target->ic_state() == MONOMORPHIC || case Code::COMPARE_IC:
target->ic_state() == MEGAMORPHIC) { case Code::TO_BOOLEAN_IC:
SetInfo(ast_id, target); SetInfo(ast_id, target);
} break;
break;
case Code::STUB:
case Code::UNARY_OP_IC: if (target->major_key() == CodeStub::CallFunction &&
case Code::BINARY_OP_IC: target->has_function_cache()) {
case Code::COMPARE_IC: Object* value = CallFunctionStub::GetCachedValue(reloc_entry.pc());
case Code::TO_BOOLEAN_IC: if (value->IsJSFunction()) {
SetInfo(ast_id, target); SetInfo(ast_id, value);
break; }
case Code::STUB:
if (target->major_key() == CodeStub::CallFunction &&
target->has_function_cache()) {
Object* value = CallFunctionStub::GetCachedValue(target_address);
if (value->IsJSFunction()) {
SetInfo(ast_id, value);
} }
} break;
break;
default: default:
break; break;
}
} }
} }
......
...@@ -277,7 +277,6 @@ class TypeFeedbackOracle BASE_EMBEDDED { ...@@ -277,7 +277,6 @@ class TypeFeedbackOracle BASE_EMBEDDED {
byte* old_start, byte* old_start,
byte* new_start); byte* new_start);
void ProcessRelocInfos(ZoneList<RelocInfo>* infos); void ProcessRelocInfos(ZoneList<RelocInfo>* infos);
void ProcessTargetAt(Address target_address, unsigned ast_id);
// Returns an element from the backing store. Returns undefined if // Returns an element from the backing store. Returns undefined if
// there is no information. // there is no information.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment