Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: src/hydrogen.cc

Issue 6577036: [Isolates] Merge from bleeding_edge to isolates, revisions 6100-6300. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 121
122 HSimulate* HBasicBlock::CreateSimulate(int id) { 122 HSimulate* HBasicBlock::CreateSimulate(int id) {
123 ASSERT(HasEnvironment()); 123 ASSERT(HasEnvironment());
124 HEnvironment* environment = last_environment(); 124 HEnvironment* environment = last_environment();
125 ASSERT(id == AstNode::kNoNumber || 125 ASSERT(id == AstNode::kNoNumber ||
126 environment->closure()->shared()->VerifyBailoutId(id)); 126 environment->closure()->shared()->VerifyBailoutId(id));
127 127
128 int push_count = environment->push_count(); 128 int push_count = environment->push_count();
129 int pop_count = environment->pop_count(); 129 int pop_count = environment->pop_count();
130 130
131 int length = environment->values()->length(); 131 int length = environment->length();
132 HSimulate* instr = new HSimulate(id, pop_count, length); 132 HSimulate* instr = new HSimulate(id, pop_count, length);
133 for (int i = push_count - 1; i >= 0; --i) { 133 for (int i = push_count - 1; i >= 0; --i) {
134 instr->AddPushedValue(environment->ExpressionStackAt(i)); 134 instr->AddPushedValue(environment->ExpressionStackAt(i));
135 } 135 }
136 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { 136 for (int i = 0; i < environment->assigned_variables()->length(); ++i) {
137 int index = environment->assigned_variables()->at(i); 137 int index = environment->assigned_variables()->at(i);
138 instr->AddAssignedValue(index, environment->Lookup(index)); 138 instr->AddAssignedValue(index, environment->Lookup(index));
139 } 139 }
140 environment->ClearHistory(); 140 environment->ClearHistory();
141 return instr; 141 return instr;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 215
216 216
217 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { 217 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) {
218 if (!predecessors_.is_empty()) { 218 if (!predecessors_.is_empty()) {
219 // Only loop header blocks can have a predecessor added after 219 // Only loop header blocks can have a predecessor added after
220 // instructions have been added to the block (they have phis for all 220 // instructions have been added to the block (they have phis for all
221 // values in the environment, these phis may be eliminated later). 221 // values in the environment, these phis may be eliminated later).
222 ASSERT(IsLoopHeader() || first_ == NULL); 222 ASSERT(IsLoopHeader() || first_ == NULL);
223 HEnvironment* incoming_env = pred->last_environment(); 223 HEnvironment* incoming_env = pred->last_environment();
224 if (IsLoopHeader()) { 224 if (IsLoopHeader()) {
225 ASSERT(phis()->length() == incoming_env->values()->length()); 225 ASSERT(phis()->length() == incoming_env->length());
226 for (int i = 0; i < phis_.length(); ++i) { 226 for (int i = 0; i < phis_.length(); ++i) {
227 phis_[i]->AddInput(incoming_env->values()->at(i)); 227 phis_[i]->AddInput(incoming_env->values()->at(i));
228 } 228 }
229 } else { 229 } else {
230 last_environment()->AddIncomingEdge(this, pred->last_environment()); 230 last_environment()->AddIncomingEdge(this, pred->last_environment());
231 } 231 }
232 } else if (!HasEnvironment() && !IsFinished()) { 232 } else if (!HasEnvironment() && !IsFinished()) {
233 ASSERT(!IsLoopHeader()); 233 ASSERT(!IsLoopHeader());
234 SetInitialEnvironment(pred->last_environment()->Copy()); 234 SetInitialEnvironment(pred->last_environment()->Copy());
235 } 235 }
(...skipping 1739 matching lines...) Expand 10 before | Expand all | Expand 10 after
1975 } 1975 }
1976 } 1976 }
1977 1977
1978 1978
1979 // Implementation of utility classes to represent an expression's context in 1979 // Implementation of utility classes to represent an expression's context in
1980 // the AST. 1980 // the AST.
1981 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) 1981 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind)
1982 : owner_(owner), kind_(kind), outer_(owner->ast_context()) { 1982 : owner_(owner), kind_(kind), outer_(owner->ast_context()) {
1983 owner->set_ast_context(this); // Push. 1983 owner->set_ast_context(this); // Push.
1984 #ifdef DEBUG 1984 #ifdef DEBUG
1985 original_count_ = owner->environment()->total_count(); 1985 original_length_ = owner->environment()->length();
1986 #endif 1986 #endif
1987 } 1987 }
1988 1988
1989 1989
1990 AstContext::~AstContext() { 1990 AstContext::~AstContext() {
1991 owner_->set_ast_context(outer_); // Pop. 1991 owner_->set_ast_context(outer_); // Pop.
1992 } 1992 }
1993 1993
1994 1994
1995 EffectContext::~EffectContext() { 1995 EffectContext::~EffectContext() {
1996 ASSERT(owner()->HasStackOverflow() || 1996 ASSERT(owner()->HasStackOverflow() ||
1997 !owner()->subgraph()->HasExit() || 1997 !owner()->subgraph()->HasExit() ||
1998 owner()->environment()->total_count() == original_count_); 1998 owner()->environment()->length() == original_length_);
1999 } 1999 }
2000 2000
2001 2001
2002 ValueContext::~ValueContext() { 2002 ValueContext::~ValueContext() {
2003 ASSERT(owner()->HasStackOverflow() || 2003 ASSERT(owner()->HasStackOverflow() ||
2004 !owner()->subgraph()->HasExit() || 2004 !owner()->subgraph()->HasExit() ||
2005 owner()->environment()->total_count() == original_count_ + 1); 2005 owner()->environment()->length() == original_length_ + 1);
2006 } 2006 }
2007 2007
2008 2008
2009 void EffectContext::ReturnValue(HValue* value) { 2009 void EffectContext::ReturnValue(HValue* value) {
2010 // The value is simply ignored. 2010 // The value is simply ignored.
2011 } 2011 }
2012 2012
2013 2013
2014 void ValueContext::ReturnValue(HValue* value) { 2014 void ValueContext::ReturnValue(HValue* value) {
2015 // The value is tracked in the bailout environment, and communicated 2015 // The value is tracked in the bailout environment, and communicated
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
2336 2336
2337 // Set the initial values of parameters including "this". "This" has 2337 // Set the initial values of parameters including "this". "This" has
2338 // parameter index 0. 2338 // parameter index 0.
2339 int count = scope->num_parameters() + 1; 2339 int count = scope->num_parameters() + 1;
2340 for (int i = 0; i < count; ++i) { 2340 for (int i = 0; i < count; ++i) {
2341 HInstruction* parameter = AddInstruction(new HParameter(i)); 2341 HInstruction* parameter = AddInstruction(new HParameter(i));
2342 environment()->Bind(i, parameter); 2342 environment()->Bind(i, parameter);
2343 } 2343 }
2344 2344
2345 // Set the initial values of stack-allocated locals. 2345 // Set the initial values of stack-allocated locals.
2346 for (int i = count; i < environment()->values()->length(); ++i) { 2346 for (int i = count; i < environment()->length(); ++i) {
2347 environment()->Bind(i, undefined_constant); 2347 environment()->Bind(i, undefined_constant);
2348 } 2348 }
2349 2349
2350 // Handle the arguments and arguments shadow variables specially (they do 2350 // Handle the arguments and arguments shadow variables specially (they do
2351 // not have declarations). 2351 // not have declarations).
2352 if (scope->arguments() != NULL) { 2352 if (scope->arguments() != NULL) {
2353 HArgumentsObject* object = new HArgumentsObject; 2353 HArgumentsObject* object = new HArgumentsObject;
2354 AddInstruction(object); 2354 AddInstruction(object);
2355 graph()->SetArgumentsObject(object); 2355 graph()->SetArgumentsObject(object);
2356 environment()->Bind(scope->arguments(), object); 2356 environment()->Bind(scope->arguments(), object);
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
2695 HValue* true_value = graph()->GetConstantTrue(); 2695 HValue* true_value = graph()->GetConstantTrue();
2696 HBranch* branch = new HBranch(non_osr_entry, osr_entry, true_value); 2696 HBranch* branch = new HBranch(non_osr_entry, osr_entry, true_value);
2697 exit_block()->Finish(branch); 2697 exit_block()->Finish(branch);
2698 2698
2699 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); 2699 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock();
2700 non_osr_entry->Goto(loop_predecessor); 2700 non_osr_entry->Goto(loop_predecessor);
2701 2701
2702 int osr_entry_id = statement->OsrEntryId(); 2702 int osr_entry_id = statement->OsrEntryId();
2703 // We want the correct environment at the OsrEntry instruction. Build 2703 // We want the correct environment at the OsrEntry instruction. Build
2704 // it explicitly. The expression stack should be empty. 2704 // it explicitly. The expression stack should be empty.
2705 int count = osr_entry->last_environment()->total_count(); 2705 int count = osr_entry->last_environment()->length();
2706 ASSERT(count == (osr_entry->last_environment()->parameter_count() + 2706 ASSERT(count == (osr_entry->last_environment()->parameter_count() +
2707 osr_entry->last_environment()->local_count())); 2707 osr_entry->last_environment()->local_count()));
2708 for (int i = 0; i < count; ++i) { 2708 for (int i = 0; i < count; ++i) {
2709 HUnknownOSRValue* unknown = new HUnknownOSRValue; 2709 HUnknownOSRValue* unknown = new HUnknownOSRValue;
2710 osr_entry->AddInstruction(unknown); 2710 osr_entry->AddInstruction(unknown);
2711 osr_entry->last_environment()->Bind(i, unknown); 2711 osr_entry->last_environment()->Bind(i, unknown);
2712 } 2712 }
2713 2713
2714 osr_entry->AddSimulate(osr_entry_id); 2714 osr_entry->AddSimulate(osr_entry_id);
2715 osr_entry->AddInstruction(new HOsrEntry(osr_entry_id)); 2715 osr_entry->AddInstruction(new HOsrEntry(osr_entry_id));
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
3096 current_subgraph_->exit_block()->Finish( 3096 current_subgraph_->exit_block()->Finish(
3097 new HCompareMapAndBranch(receiver, 3097 new HCompareMapAndBranch(receiver,
3098 Handle<Map>(maps->first()), 3098 Handle<Map>(maps->first()),
3099 subgraphs->first()->entry_block(), 3099 subgraphs->first()->entry_block(),
3100 else_subgraph->entry_block())); 3100 else_subgraph->entry_block()));
3101 3101
3102 // Join all the call subgraphs in a new basic block and make 3102 // Join all the call subgraphs in a new basic block and make
3103 // this basic block the current basic block. 3103 // this basic block the current basic block.
3104 HBasicBlock* join_block = graph_->CreateBasicBlock(); 3104 HBasicBlock* join_block = graph_->CreateBasicBlock();
3105 for (int i = 0; i < subgraphs->length(); ++i) { 3105 for (int i = 0; i < subgraphs->length(); ++i) {
3106 if (subgraphs->at(i)->HasExit()) { 3106 HSubgraph* subgraph = subgraphs->at(i);
3107 subgraphs->at(i)->exit_block()->Goto(join_block); 3107 if (subgraph->HasExit()) {
3108 // In an effect context the value of the type switch is not needed.
3109 // There is no need to merge it at the join block only to discard it.
3110 HBasicBlock* subgraph_exit = subgraph->exit_block();
3111 if (ast_context()->IsEffect()) {
3112 subgraph_exit->last_environment()->Drop(1);
3113 }
3114 subgraph_exit->Goto(join_block);
3108 } 3115 }
3109 } 3116 }
3110 3117
3111 if (join_block->predecessors()->is_empty()) return NULL; 3118 if (join_block->predecessors()->is_empty()) return NULL;
3112 join_block->SetJoinId(join_id); 3119 join_block->SetJoinId(join_id);
3113 return join_block; 3120 return join_block;
3114 } 3121 }
3115 3122
3116 3123
3117 // Sets the lookup result and returns true if the store can be inlined. 3124 // Sets the lookup result and returns true if the store can be inlined.
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
3235 } 3242 }
3236 } 3243 }
3237 3244
3238 // If none of the properties were named fields we generate a 3245 // If none of the properties were named fields we generate a
3239 // generic store. 3246 // generic store.
3240 if (maps.length() == 0) { 3247 if (maps.length() == 0) {
3241 HInstruction* instr = new HStoreNamedGeneric(object, name, value); 3248 HInstruction* instr = new HStoreNamedGeneric(object, name, value);
3242 Push(value); 3249 Push(value);
3243 instr->set_position(expr->position()); 3250 instr->set_position(expr->position());
3244 AddInstruction(instr); 3251 AddInstruction(instr);
3245 if (instr->HasSideEffects()) AddSimulate(expr->id()); 3252 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3253 ast_context()->ReturnValue(Pop());
3246 } else { 3254 } else {
3247 // Build subgraph for generic store through IC. 3255 // Build subgraph for generic store through IC.
3248 { 3256 {
3249 HSubgraph* subgraph = CreateBranchSubgraph(environment()); 3257 HSubgraph* subgraph = CreateBranchSubgraph(environment());
3250 SubgraphScope scope(this, subgraph); 3258 SubgraphScope scope(this, subgraph);
3251 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { 3259 if (!needs_generic && FLAG_deoptimize_uncommon_cases) {
3252 subgraph->FinishExit(new HDeoptimize()); 3260 subgraph->FinishExit(new HDeoptimize());
3253 } else { 3261 } else {
3254 HInstruction* instr = new HStoreNamedGeneric(object, name, value); 3262 HInstruction* instr = new HStoreNamedGeneric(object, name, value);
3255 Push(value); 3263 Push(value);
3256 instr->set_position(expr->position()); 3264 instr->set_position(expr->position());
3257 AddInstruction(instr); 3265 AddInstruction(instr);
3258 } 3266 }
3259 subgraphs.Add(subgraph); 3267 subgraphs.Add(subgraph);
3260 } 3268 }
3261 3269
3262 HBasicBlock* new_exit_block = 3270 HBasicBlock* new_exit_block =
3263 BuildTypeSwitch(&maps, &subgraphs, object, expr->AssignmentId()); 3271 BuildTypeSwitch(&maps, &subgraphs, object, expr->id());
3264 subgraph()->set_exit_block(new_exit_block); 3272 subgraph()->set_exit_block(new_exit_block);
3273 // In an effect context, we did not materialized the value in the
3274 // predecessor environments so there's no need to handle it here.
3275 if (subgraph()->HasExit() && !ast_context()->IsEffect()) {
3276 ast_context()->ReturnValue(Pop());
3277 }
3265 } 3278 }
3266
3267 if (subgraph()->HasExit()) ast_context()->ReturnValue(Pop());
3268 } 3279 }
3269 3280
3270 3281
3271 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 3282 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
3272 Property* prop = expr->target()->AsProperty(); 3283 Property* prop = expr->target()->AsProperty();
3273 ASSERT(prop != NULL); 3284 ASSERT(prop != NULL);
3274 expr->RecordTypeFeedback(oracle()); 3285 expr->RecordTypeFeedback(oracle());
3275 VISIT_FOR_VALUE(prop->obj()); 3286 VISIT_FOR_VALUE(prop->obj());
3276 3287
3277 HValue* value = NULL; 3288 HValue* value = NULL;
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
3541 } else { 3552 } else {
3542 needs_generic = true; 3553 needs_generic = true;
3543 } 3554 }
3544 } 3555 }
3545 3556
3546 // If none of the properties were named fields we generate a 3557 // If none of the properties were named fields we generate a
3547 // generic load. 3558 // generic load.
3548 if (maps.length() == 0) { 3559 if (maps.length() == 0) {
3549 HInstruction* instr = BuildLoadNamedGeneric(object, expr); 3560 HInstruction* instr = BuildLoadNamedGeneric(object, expr);
3550 instr->set_position(expr->position()); 3561 instr->set_position(expr->position());
3551 PushAndAdd(instr); 3562 ast_context()->ReturnInstruction(instr, expr->id());
3552 if (instr->HasSideEffects()) AddSimulate(expr->id());
3553 } else { 3563 } else {
3554 // Build subgraph for generic load through IC. 3564 // Build subgraph for generic load through IC.
3555 { 3565 {
3556 HSubgraph* subgraph = CreateBranchSubgraph(environment()); 3566 HSubgraph* subgraph = CreateBranchSubgraph(environment());
3557 SubgraphScope scope(this, subgraph); 3567 SubgraphScope scope(this, subgraph);
3558 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { 3568 if (!needs_generic && FLAG_deoptimize_uncommon_cases) {
3559 subgraph->FinishExit(new HDeoptimize()); 3569 subgraph->FinishExit(new HDeoptimize());
3560 } else { 3570 } else {
3561 HInstruction* instr = BuildLoadNamedGeneric(object, expr); 3571 HInstruction* instr = BuildLoadNamedGeneric(object, expr);
3562 instr->set_position(expr->position()); 3572 instr->set_position(expr->position());
3563 PushAndAdd(instr); 3573 PushAndAdd(instr);
3564 } 3574 }
3565 subgraphs.Add(subgraph); 3575 subgraphs.Add(subgraph);
3566 } 3576 }
3567 3577
3568 HBasicBlock* new_exit_block = 3578 HBasicBlock* new_exit_block =
3569 BuildTypeSwitch(&maps, &subgraphs, object, expr->id()); 3579 BuildTypeSwitch(&maps, &subgraphs, object, expr->id());
3570 subgraph()->set_exit_block(new_exit_block); 3580 subgraph()->set_exit_block(new_exit_block);
3581 // In an effect context, we did not materialized the value in the
3582 // predecessor environments so there's no need to handle it here.
3583 if (subgraph()->HasExit() && !ast_context()->IsEffect()) {
3584 ast_context()->ReturnValue(Pop());
3585 }
3571 } 3586 }
3572
3573 if (subgraph()->HasExit()) ast_context()->ReturnValue(Pop());
3574 } 3587 }
3575 3588
3576 3589
3577 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, 3590 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
3578 Property* expr, 3591 Property* expr,
3579 Handle<Map> type, 3592 Handle<Map> type,
3580 LookupResult* lookup, 3593 LookupResult* lookup,
3581 bool smi_and_map_check) { 3594 bool smi_and_map_check) {
3582 if (smi_and_map_check) { 3595 if (smi_and_map_check) {
3583 AddInstruction(new HCheckNonSmi(object)); 3596 AddInstruction(new HCheckNonSmi(object));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3636 3649
3637 3650
3638 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object, 3651 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object,
3639 HValue* key, 3652 HValue* key,
3640 Property* expr) { 3653 Property* expr) {
3641 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); 3654 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic());
3642 AddInstruction(new HCheckNonSmi(object)); 3655 AddInstruction(new HCheckNonSmi(object));
3643 Handle<Map> map = expr->GetMonomorphicReceiverType(); 3656 Handle<Map> map = expr->GetMonomorphicReceiverType();
3644 ASSERT(map->has_fast_elements()); 3657 ASSERT(map->has_fast_elements());
3645 AddInstruction(new HCheckMap(object, map)); 3658 AddInstruction(new HCheckMap(object, map));
3646 HInstruction* elements = AddInstruction(new HLoadElements(object)); 3659 bool is_array = (map->instance_type() == JS_ARRAY_TYPE);
3647 HInstruction* length = AddInstruction(new HArrayLength(elements)); 3660 HLoadElements* elements = new HLoadElements(object);
3648 AddInstruction(new HBoundsCheck(key, length)); 3661 HInstruction* length = NULL;
3662 if (is_array) {
3663 length = AddInstruction(new HJSArrayLength(object));
3664 AddInstruction(new HBoundsCheck(key, length));
3665 AddInstruction(elements);
3666 } else {
3667 AddInstruction(elements);
3668 length = AddInstruction(new HFixedArrayLength(elements));
3669 AddInstruction(new HBoundsCheck(key, length));
3670 }
3649 return new HLoadKeyedFastElement(elements, key); 3671 return new HLoadKeyedFastElement(elements, key);
3650 } 3672 }
3651 3673
3652 3674
3653 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, 3675 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object,
3654 HValue* key, 3676 HValue* key,
3655 HValue* value) { 3677 HValue* value) {
3656 return new HStoreKeyedGeneric(object, key, value); 3678 return new HStoreKeyedGeneric(object, key, value);
3657 } 3679 }
3658 3680
3659 3681
3660 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, 3682 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object,
3661 HValue* key, 3683 HValue* key,
3662 HValue* val, 3684 HValue* val,
3663 Expression* expr) { 3685 Expression* expr) {
3664 ASSERT(expr->IsMonomorphic()); 3686 ASSERT(expr->IsMonomorphic());
3665 AddInstruction(new HCheckNonSmi(object)); 3687 AddInstruction(new HCheckNonSmi(object));
3666 Handle<Map> map = expr->GetMonomorphicReceiverType(); 3688 Handle<Map> map = expr->GetMonomorphicReceiverType();
3667 ASSERT(map->has_fast_elements()); 3689 ASSERT(map->has_fast_elements());
3668 AddInstruction(new HCheckMap(object, map)); 3690 AddInstruction(new HCheckMap(object, map));
3669 HInstruction* elements = AddInstruction(new HLoadElements(object)); 3691 HInstruction* elements = AddInstruction(new HLoadElements(object));
3670 AddInstruction(new HCheckMap(elements, FACTORY->fixed_array_map())); 3692 AddInstruction(new HCheckMap(elements, FACTORY->fixed_array_map()));
3671 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); 3693 bool is_array = (map->instance_type() == JS_ARRAY_TYPE);
3672 HInstruction* length = NULL; 3694 HInstruction* length = NULL;
3673 if (is_array) { 3695 if (is_array) {
3674 length = AddInstruction(new HArrayLength(object)); 3696 length = AddInstruction(new HJSArrayLength(object));
3675 } else { 3697 } else {
3676 length = AddInstruction(new HArrayLength(elements)); 3698 length = AddInstruction(new HFixedArrayLength(elements));
3677 } 3699 }
3678 AddInstruction(new HBoundsCheck(key, length)); 3700 AddInstruction(new HBoundsCheck(key, length));
3679 return new HStoreKeyedFastElement(elements, key, val); 3701 return new HStoreKeyedFastElement(elements, key, val);
3680 } 3702 }
3681 3703
3682 3704
3683 bool HGraphBuilder::TryArgumentsAccess(Property* expr) { 3705 bool HGraphBuilder::TryArgumentsAccess(Property* expr) {
3684 VariableProxy* proxy = expr->obj()->AsVariableProxy(); 3706 VariableProxy* proxy = expr->obj()->AsVariableProxy();
3685 if (proxy == NULL) return false; 3707 if (proxy == NULL) return false;
3686 if (!proxy->var()->IsStackAllocated()) return false; 3708 if (!proxy->var()->IsStackAllocated()) return false;
(...skipping 26 matching lines...) Expand all
3713 3735
3714 if (TryArgumentsAccess(expr)) return; 3736 if (TryArgumentsAccess(expr)) return;
3715 CHECK_BAILOUT; 3737 CHECK_BAILOUT;
3716 3738
3717 VISIT_FOR_VALUE(expr->obj()); 3739 VISIT_FOR_VALUE(expr->obj());
3718 3740
3719 HInstruction* instr = NULL; 3741 HInstruction* instr = NULL;
3720 if (expr->IsArrayLength()) { 3742 if (expr->IsArrayLength()) {
3721 HValue* array = Pop(); 3743 HValue* array = Pop();
3722 AddInstruction(new HCheckNonSmi(array)); 3744 AddInstruction(new HCheckNonSmi(array));
3723 instr = new HArrayLength(array); 3745 AddInstruction(new HCheckInstanceType(array, JS_ARRAY_TYPE, JS_ARRAY_TYPE));
3746 instr = new HJSArrayLength(array);
3747
3748 } else if (expr->IsFunctionPrototype()) {
3749 HValue* function = Pop();
3750 AddInstruction(new HCheckNonSmi(function));
3751 instr = new HLoadFunctionPrototype(function);
3724 3752
3725 } else if (expr->key()->IsPropertyName()) { 3753 } else if (expr->key()->IsPropertyName()) {
3726 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 3754 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
3727 ZoneMapList* types = expr->GetReceiverTypes(); 3755 ZoneMapList* types = expr->GetReceiverTypes();
3728 3756
3729 HValue* obj = Pop(); 3757 HValue* obj = Pop();
3730 if (expr->IsMonomorphic()) { 3758 if (expr->IsMonomorphic()) {
3731 instr = BuildLoadNamed(obj, expr, types->first(), name); 3759 instr = BuildLoadNamed(obj, expr, types->first(), name);
3732 } else if (types != NULL && types->length() > 1) { 3760 } else if (types != NULL && types->length() > 1) {
3733 HandlePolymorphicLoadNamedField(expr, obj, types, name); 3761 HandlePolymorphicLoadNamedField(expr, obj, types, name);
(...skipping 26 matching lines...) Expand all
3760 Handle<Map> receiver_map, 3788 Handle<Map> receiver_map,
3761 bool smi_and_map_check) { 3789 bool smi_and_map_check) {
3762 // Constant functions have the nice property that the map will change if they 3790 // Constant functions have the nice property that the map will change if they
3763 // are overwritten. Therefore it is enough to check the map of the holder and 3791 // are overwritten. Therefore it is enough to check the map of the holder and
3764 // its prototypes. 3792 // its prototypes.
3765 if (smi_and_map_check) { 3793 if (smi_and_map_check) {
3766 AddInstruction(new HCheckNonSmi(receiver)); 3794 AddInstruction(new HCheckNonSmi(receiver));
3767 AddInstruction(new HCheckMap(receiver, receiver_map)); 3795 AddInstruction(new HCheckMap(receiver, receiver_map));
3768 } 3796 }
3769 if (!expr->holder().is_null()) { 3797 if (!expr->holder().is_null()) {
3770 AddInstruction(new HCheckPrototypeMaps(receiver, 3798 AddInstruction(new HCheckPrototypeMaps(
3771 expr->holder(), 3799 Handle<JSObject>(JSObject::cast(receiver_map->prototype())),
3772 receiver_map)); 3800 expr->holder()));
3773 } 3801 }
3774 } 3802 }
3775 3803
3776 3804
3777 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, 3805 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
3778 HValue* receiver, 3806 HValue* receiver,
3779 ZoneMapList* types, 3807 ZoneMapList* types,
3780 Handle<String> name) { 3808 Handle<String> name) {
3781 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 3809 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
3782 int number_of_types = Min(types->length(), kMaxCallPolymorphism); 3810 int number_of_types = Min(types->length(), kMaxCallPolymorphism);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
3834 call->set_position(expr->position()); 3862 call->set_position(expr->position());
3835 ProcessCall(call); 3863 ProcessCall(call);
3836 PushAndAdd(call); 3864 PushAndAdd(call);
3837 } 3865 }
3838 subgraphs.Add(subgraph); 3866 subgraphs.Add(subgraph);
3839 } 3867 }
3840 3868
3841 HBasicBlock* new_exit_block = 3869 HBasicBlock* new_exit_block =
3842 BuildTypeSwitch(&maps, &subgraphs, receiver, expr->id()); 3870 BuildTypeSwitch(&maps, &subgraphs, receiver, expr->id());
3843 subgraph()->set_exit_block(new_exit_block); 3871 subgraph()->set_exit_block(new_exit_block);
3844 if (new_exit_block != NULL) ast_context()->ReturnValue(Pop()); 3872 // In an effect context, we did not materialized the value in the
3873 // predecessor environments so there's no need to handle it here.
3874 if (new_exit_block != NULL && !ast_context()->IsEffect()) {
3875 ast_context()->ReturnValue(Pop());
3876 }
3845 } 3877 }
3846 } 3878 }
3847 3879
3848 3880
3849 void HGraphBuilder::TraceInline(Handle<JSFunction> target, bool result) { 3881 void HGraphBuilder::TraceInline(Handle<JSFunction> target, bool result) {
3850 SmartPointer<char> callee = target->shared()->DebugName()->ToCString(); 3882 SmartPointer<char> callee = target->shared()->DebugName()->ToCString();
3851 SmartPointer<char> caller = 3883 SmartPointer<char> caller =
3852 graph()->info()->function()->debug_name()->ToCString(); 3884 graph()->info()->function()->debug_name()->ToCString();
3853 if (result) { 3885 if (result) {
3854 PrintF("Inlined %s called from %s.\n", *callee, *caller); 3886 PrintF("Inlined %s called from %s.\n", *callee, *caller);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
3970 if_false->MarkAsInlineReturnTarget(); 4002 if_false->MarkAsInlineReturnTarget();
3971 // AstContext constructor pushes on the context stack. 4003 // AstContext constructor pushes on the context stack.
3972 test_context = new TestContext(this, if_true, if_false); 4004 test_context = new TestContext(this, if_true, if_false);
3973 function_return_ = NULL; 4005 function_return_ = NULL;
3974 } else { 4006 } else {
3975 // Inlined body is treated as if it occurs in the original call context. 4007 // Inlined body is treated as if it occurs in the original call context.
3976 function_return_ = graph()->CreateBasicBlock(); 4008 function_return_ = graph()->CreateBasicBlock();
3977 function_return_->MarkAsInlineReturnTarget(); 4009 function_return_->MarkAsInlineReturnTarget();
3978 } 4010 }
3979 call_context_ = ast_context(); 4011 call_context_ = ast_context();
3980 TypeFeedbackOracle new_oracle(Handle<Code>(shared->code())); 4012 TypeFeedbackOracle new_oracle(
4013 Handle<Code>(shared->code()),
4014 Handle<Context>(target->context()->global_context()));
3981 oracle_ = &new_oracle; 4015 oracle_ = &new_oracle;
3982 graph()->info()->SetOsrAstId(AstNode::kNoNumber); 4016 graph()->info()->SetOsrAstId(AstNode::kNoNumber);
3983 4017
3984 HSubgraph* body = CreateInlinedSubgraph(env, target, function); 4018 HSubgraph* body = CreateInlinedSubgraph(env, target, function);
3985 body->exit_block()->AddInstruction(new HEnterInlined(target, function)); 4019 body->exit_block()->AddInstruction(new HEnterInlined(target, function));
3986 AddToSubgraph(body, function->body()); 4020 AddToSubgraph(body, function->body());
3987 if (HasStackOverflow()) { 4021 if (HasStackOverflow()) {
3988 // Bail out if the inline function did, as we cannot residualize a call 4022 // Bail out if the inline function did, as we cannot residualize a call
3989 // instead. 4023 // instead.
3990 delete test_context; 4024 delete test_context;
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
4172 if (!name->IsEqualTo(CStrVector("apply"))) return false; 4206 if (!name->IsEqualTo(CStrVector("apply"))) return false;
4173 4207
4174 ZoneList<Expression*>* args = expr->arguments(); 4208 ZoneList<Expression*>* args = expr->arguments();
4175 if (args->length() != 2) return false; 4209 if (args->length() != 2) return false;
4176 4210
4177 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); 4211 VariableProxy* arg_two = args->at(1)->AsVariableProxy();
4178 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; 4212 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
4179 HValue* arg_two_value = environment()->Lookup(arg_two->var()); 4213 HValue* arg_two_value = environment()->Lookup(arg_two->var());
4180 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; 4214 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
4181 4215
4182 if (!expr->IsMonomorphic()) return false; 4216 if (!expr->IsMonomorphic() ||
4217 expr->check_type() != RECEIVER_MAP_CHECK) return false;
4183 4218
4184 // Found pattern f.apply(receiver, arguments). 4219 // Found pattern f.apply(receiver, arguments).
4185 VisitForValue(prop->obj()); 4220 VisitForValue(prop->obj());
4186 if (HasStackOverflow()) return false; 4221 if (HasStackOverflow()) return false;
4187 HValue* function = Pop(); 4222 HValue* function = Pop();
4188 VisitForValue(args->at(0)); 4223 VisitForValue(args->at(0));
4189 if (HasStackOverflow()) return false; 4224 if (HasStackOverflow()) return false;
4190 HValue* receiver = Pop(); 4225 HValue* receiver = Pop();
4191 HInstruction* elements = AddInstruction(new HArgumentsElements); 4226 HInstruction* elements = AddInstruction(new HArgumentsElements);
4192 HInstruction* length = AddInstruction(new HArgumentsLength(elements)); 4227 HInstruction* length = AddInstruction(new HArgumentsLength(elements));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4241 HValue* receiver = VisitArgument(prop->obj()); 4276 HValue* receiver = VisitArgument(prop->obj());
4242 CHECK_BAILOUT; 4277 CHECK_BAILOUT;
4243 VisitArgumentList(expr->arguments()); 4278 VisitArgumentList(expr->arguments());
4244 CHECK_BAILOUT; 4279 CHECK_BAILOUT;
4245 4280
4246 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 4281 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
4247 4282
4248 expr->RecordTypeFeedback(oracle()); 4283 expr->RecordTypeFeedback(oracle());
4249 ZoneMapList* types = expr->GetReceiverTypes(); 4284 ZoneMapList* types = expr->GetReceiverTypes();
4250 4285
4251 if (expr->IsMonomorphic()) { 4286 if (expr->IsMonomorphic() && expr->check_type() == RECEIVER_MAP_CHECK) {
4252 AddCheckConstantFunction(expr, receiver, types->first(), true); 4287 AddCheckConstantFunction(expr, receiver, types->first(), true);
4253 4288
4254 if (TryMathFunctionInline(expr)) { 4289 if (TryMathFunctionInline(expr)) {
4255 return; 4290 return;
4256 } else if (TryInline(expr)) { 4291 } else if (TryInline(expr)) {
4257 if (subgraph()->HasExit()) { 4292 if (subgraph()->HasExit()) {
4258 HValue* return_value = Pop(); 4293 HValue* return_value = Pop();
4259 // If we inlined a function in a test context then we need to emit 4294 // If we inlined a function in a test context then we need to emit
4260 // a simulate here to shadow the ones at the end of the 4295 // a simulate here to shadow the ones at the end of the
4261 // predecessor blocks. Those environments contain the return 4296 // predecessor blocks. Those environments contain the return
4262 // value on top and do not correspond to any actual state of the 4297 // value on top and do not correspond to any actual state of the
4263 // unoptimized code. 4298 // unoptimized code.
4264 if (ast_context()->IsEffect()) AddSimulate(expr->id()); 4299 if (ast_context()->IsEffect()) AddSimulate(expr->id());
4265 ast_context()->ReturnValue(return_value); 4300 ast_context()->ReturnValue(return_value);
4266 } 4301 }
4267 return; 4302 return;
4268 } else { 4303 } else {
4269 // Check for bailout, as the TryInline call in the if condition above 4304 // Check for bailout, as the TryInline call in the if condition above
4270 // might return false due to bailout during hydrogen processing. 4305 // might return false due to bailout during hydrogen processing.
4271 CHECK_BAILOUT; 4306 CHECK_BAILOUT;
4272 call = new HCallConstantFunction(expr->target(), argument_count); 4307 call = new HCallConstantFunction(expr->target(), argument_count);
4273 } 4308 }
4274 4309
4275 } else if (types != NULL && types->length() > 1) { 4310 } else if (types != NULL && types->length() > 1) {
4311 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK);
4276 HandlePolymorphicCallNamed(expr, receiver, types, name); 4312 HandlePolymorphicCallNamed(expr, receiver, types, name);
4277 return; 4313 return;
4278 4314
4279 } else { 4315 } else {
4280 call = new HCallNamed(name, argument_count); 4316 call = new HCallNamed(name, argument_count);
4281 } 4317 }
4282 4318
4283 } else { 4319 } else {
4284 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 4320 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
4285 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); 4321 bool global_call = (var != NULL) && var->is_global() && !var->is_this();
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
4840 VISIT_FOR_VALUE(expr->left()); 4876 VISIT_FOR_VALUE(expr->left());
4841 VISIT_FOR_VALUE(expr->right()); 4877 VISIT_FOR_VALUE(expr->right());
4842 4878
4843 HValue* right = Pop(); 4879 HValue* right = Pop();
4844 HValue* left = Pop(); 4880 HValue* left = Pop();
4845 Token::Value op = expr->op(); 4881 Token::Value op = expr->op();
4846 4882
4847 TypeInfo info = oracle()->CompareType(expr, TypeFeedbackOracle::RESULT); 4883 TypeInfo info = oracle()->CompareType(expr, TypeFeedbackOracle::RESULT);
4848 HInstruction* instr = NULL; 4884 HInstruction* instr = NULL;
4849 if (op == Token::INSTANCEOF) { 4885 if (op == Token::INSTANCEOF) {
4850 instr = new HInstanceOf(left, right); 4886 // Check to see if the rhs of the instanceof is a global function not
4887 // residing in new space. If it is we assume that the function will stay the
4888 // same.
4889 Handle<JSFunction> target = Handle<JSFunction>::null();
4890 Variable* var = expr->right()->AsVariableProxy()->AsVariable();
4891 bool global_function = (var != NULL) && var->is_global() && !var->is_this();
4892 CompilationInfo* info = graph()->info();
4893 if (global_function &&
4894 info->has_global_object() &&
4895 !info->global_object()->IsAccessCheckNeeded()) {
4896 Handle<String> name = var->name();
4897 Handle<GlobalObject> global(info->global_object());
4898 LookupResult lookup;
4899 global->Lookup(*name, &lookup);
4900 if (lookup.IsProperty() &&
4901 lookup.type() == NORMAL &&
4902 lookup.GetValue()->IsJSFunction()) {
4903 Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue()));
4904 // If the function is in new space we assume it's more likely to
4905 // change and thus prefer the general IC code.
4906 if (!info->isolate()->heap()->InNewSpace(*candidate)) {
4907 target = candidate;
4908 }
4909 }
4910 }
4911
4912 // If the target is not null we have found a known global function that is
4913 // assumed to stay the same for this instanceof.
4914 if (target.is_null()) {
4915 instr = new HInstanceOf(left, right);
4916 } else {
4917 AddInstruction(new HCheckFunction(right, target));
4918 instr = new HInstanceOfKnownGlobal(left, target);
4919 }
4851 } else if (op == Token::IN) { 4920 } else if (op == Token::IN) {
4852 BAILOUT("Unsupported comparison: in"); 4921 BAILOUT("Unsupported comparison: in");
4853 } else if (info.IsNonPrimitive()) { 4922 } else if (info.IsNonPrimitive()) {
4854 switch (op) { 4923 switch (op) {
4855 case Token::EQ: 4924 case Token::EQ:
4856 case Token::EQ_STRICT: { 4925 case Token::EQ_STRICT: {
4926 AddInstruction(new HCheckNonSmi(left));
4857 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left)); 4927 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left));
4928 AddInstruction(new HCheckNonSmi(right));
4858 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right)); 4929 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right));
4859 instr = new HCompareJSObjectEq(left, right); 4930 instr = new HCompareJSObjectEq(left, right);
4860 break; 4931 break;
4861 } 4932 }
4862 default: 4933 default:
4863 BAILOUT("Unsupported non-primitive compare"); 4934 BAILOUT("Unsupported non-primitive compare");
4864 break; 4935 break;
4865 } 4936 }
4866 } else { 4937 } else {
4867 HCompare* compare = new HCompare(left, right, op); 4938 HCompare* compare = new HCompare(left, right, op);
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
5255 parameter_count_ = parameter_count; 5326 parameter_count_ = parameter_count;
5256 local_count_ = local_count; 5327 local_count_ = local_count;
5257 5328
5258 // Avoid reallocating the temporaries' backing store on the first Push. 5329 // Avoid reallocating the temporaries' backing store on the first Push.
5259 int total = parameter_count + local_count + stack_height; 5330 int total = parameter_count + local_count + stack_height;
5260 values_.Initialize(total + 4); 5331 values_.Initialize(total + 4);
5261 for (int i = 0; i < total; ++i) values_.Add(NULL); 5332 for (int i = 0; i < total; ++i) values_.Add(NULL);
5262 } 5333 }
5263 5334
5264 5335
5336 void HEnvironment::Initialize(const HEnvironment* other) {
5337 closure_ = other->closure();
5338 values_.AddAll(other->values_);
5339 assigned_variables_.AddAll(other->assigned_variables_);
5340 parameter_count_ = other->parameter_count_;
5341 local_count_ = other->local_count_;
5342 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy.
5343 pop_count_ = other->pop_count_;
5344 push_count_ = other->push_count_;
5345 ast_id_ = other->ast_id_;
5346 }
5347
5348
5265 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { 5349 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) {
5266 ASSERT(!block->IsLoopHeader()); 5350 ASSERT(!block->IsLoopHeader());
5267 ASSERT(values_.length() == other->values_.length()); 5351 ASSERT(values_.length() == other->values_.length());
5268 5352
5269 int length = values_.length(); 5353 int length = values_.length();
5270 for (int i = 0; i < length; ++i) { 5354 for (int i = 0; i < length; ++i) {
5271 HValue* value = values_[i]; 5355 HValue* value = values_[i];
5272 if (value != NULL && value->IsPhi() && value->block() == block) { 5356 if (value != NULL && value->IsPhi() && value->block() == block) {
5273 // There is already a phi for the i'th value. 5357 // There is already a phi for the i'th value.
5274 HPhi* phi = HPhi::cast(value); 5358 HPhi* phi = HPhi::cast(value);
(...skipping 10 matching lines...) Expand all
5285 phi->AddInput(old_value); 5369 phi->AddInput(old_value);
5286 } 5370 }
5287 phi->AddInput(other->values_[i]); 5371 phi->AddInput(other->values_[i]);
5288 this->values_[i] = phi; 5372 this->values_[i] = phi;
5289 block->AddPhi(phi); 5373 block->AddPhi(phi);
5290 } 5374 }
5291 } 5375 }
5292 } 5376 }
5293 5377
5294 5378
5295 void HEnvironment::Initialize(const HEnvironment* other) { 5379 void HEnvironment::Bind(int index, HValue* value) {
5296 closure_ = other->closure(); 5380 ASSERT(value != NULL);
5297 values_.AddAll(other->values_); 5381 if (!assigned_variables_.Contains(index)) {
5298 assigned_variables_.AddAll(other->assigned_variables_); 5382 assigned_variables_.Add(index);
5299 parameter_count_ = other->parameter_count_; 5383 }
5300 local_count_ = other->local_count_; 5384 values_[index] = value;
5301 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy.
5302 pop_count_ = other->pop_count_;
5303 push_count_ = other->push_count_;
5304 ast_id_ = other->ast_id_;
5305 } 5385 }
5306 5386
5307 5387
5308 int HEnvironment::IndexFor(Variable* variable) const { 5388 bool HEnvironment::HasExpressionAt(int index) const {
5309 Slot* slot = variable->AsSlot(); 5389 return index >= parameter_count_ + local_count_;
5310 ASSERT(slot != NULL && slot->IsStackAllocated()); 5390 }
5311 if (slot->type() == Slot::PARAMETER) { 5391
5312 return slot->index() + 1; 5392
5313 } else { 5393 bool HEnvironment::ExpressionStackIsEmpty() const {
5314 return parameter_count_ + slot->index(); 5394 int first_expression = parameter_count() + local_count();
5395 ASSERT(length() >= first_expression);
5396 return length() == first_expression;
5397 }
5398
5399
5400 void HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) {
5401 int count = index_from_top + 1;
5402 int index = values_.length() - count;
5403 ASSERT(HasExpressionAt(index));
5404 // The push count must include at least the element in question or else
5405 // the new value will not be included in this environment's history.
5406 if (push_count_ < count) {
5407 // This is the same effect as popping then re-pushing 'count' elements.
5408 pop_count_ += (count - push_count_);
5409 push_count_ = count;
5410 }
5411 values_[index] = value;
5412 }
5413
5414
5415 void HEnvironment::Drop(int count) {
5416 for (int i = 0; i < count; ++i) {
5417 Pop();
5315 } 5418 }
5316 } 5419 }
5317 5420
5318 5421
5319 HEnvironment* HEnvironment::Copy() const { 5422 HEnvironment* HEnvironment::Copy() const {
5320 return new HEnvironment(this); 5423 return new HEnvironment(this);
5321 } 5424 }
5322 5425
5323 5426
5324 HEnvironment* HEnvironment::CopyWithoutHistory() const { 5427 HEnvironment* HEnvironment::CopyWithoutHistory() const {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
5369 for (int i = 0; i < local_count; ++i) { 5472 for (int i = 0; i < local_count; ++i) {
5370 inner->SetValueAt(local_base + i, undefined); 5473 inner->SetValueAt(local_base + i, undefined);
5371 } 5474 }
5372 5475
5373 inner->set_ast_id(function->id()); 5476 inner->set_ast_id(function->id());
5374 return inner; 5477 return inner;
5375 } 5478 }
5376 5479
5377 5480
5378 void HEnvironment::PrintTo(StringStream* stream) { 5481 void HEnvironment::PrintTo(StringStream* stream) {
5379 for (int i = 0; i < total_count(); i++) { 5482 for (int i = 0; i < length(); i++) {
5380 if (i == 0) stream->Add("parameters\n"); 5483 if (i == 0) stream->Add("parameters\n");
5381 if (i == parameter_count()) stream->Add("locals\n"); 5484 if (i == parameter_count()) stream->Add("locals\n");
5382 if (i == parameter_count() + local_count()) stream->Add("expressions"); 5485 if (i == parameter_count() + local_count()) stream->Add("expressions");
5383 HValue* val = values_.at(i); 5486 HValue* val = values_.at(i);
5384 stream->Add("%d: ", i); 5487 stream->Add("%d: ", i);
5385 if (val != NULL) { 5488 if (val != NULL) {
5386 val->PrintNameTo(stream); 5489 val->PrintNameTo(stream);
5387 } else { 5490 } else {
5388 stream->Add("NULL"); 5491 stream->Add("NULL");
5389 } 5492 }
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
5607 PrintF("Timing results:\n"); 5710 PrintF("Timing results:\n");
5608 int64_t sum = 0; 5711 int64_t sum = 0;
5609 for (int i = 0; i < timing_.length(); ++i) { 5712 for (int i = 0; i < timing_.length(); ++i) {
5610 sum += timing_[i]; 5713 sum += timing_[i];
5611 } 5714 }
5612 5715
5613 for (int i = 0; i < names_.length(); ++i) { 5716 for (int i = 0; i < names_.length(); ++i) {
5614 PrintF("%30s", names_[i]); 5717 PrintF("%30s", names_[i]);
5615 double ms = static_cast<double>(timing_[i]) / 1000; 5718 double ms = static_cast<double>(timing_[i]) / 1000;
5616 double percent = static_cast<double>(timing_[i]) * 100 / sum; 5719 double percent = static_cast<double>(timing_[i]) * 100 / sum;
5617 PrintF(" - %0.3f ms / %0.3f %% \n", ms, percent); 5720 PrintF(" - %7.3f ms / %4.1f %% ", ms, percent);
5721
5722 unsigned size = sizes_[i];
5723 double size_percent = static_cast<double>(size) * 100 / total_size_;
5724 PrintF(" %8u bytes / %4.1f %%\n", size, size_percent);
5618 } 5725 }
5619 PrintF("%30s - %0.3f ms \n", "Sum", static_cast<double>(sum) / 1000); 5726 PrintF("%30s - %7.3f ms %8u bytes\n", "Sum",
5727 static_cast<double>(sum) / 1000,
5728 total_size_);
5620 PrintF("---------------------------------------------------------------\n"); 5729 PrintF("---------------------------------------------------------------\n");
5621 PrintF("%30s - %0.3f ms (%0.1f times slower than full code gen)\n", 5730 PrintF("%30s - %7.3f ms (%.1f times slower than full code gen)\n",
5622 "Total", 5731 "Total",
5623 static_cast<double>(total_) / 1000, 5732 static_cast<double>(total_) / 1000,
5624 static_cast<double>(total_) / full_code_gen_); 5733 static_cast<double>(total_) / full_code_gen_);
5625 } 5734 }
5626 5735
5627 5736
5628 void HStatistics::SaveTiming(const char* name, int64_t ticks) { 5737 void HStatistics::SaveTiming(const char* name, int64_t ticks, unsigned size) {
5629 if (name == HPhase::kFullCodeGen) { 5738 if (name == HPhase::kFullCodeGen) {
5630 full_code_gen_ += ticks; 5739 full_code_gen_ += ticks;
5631 } else if (name == HPhase::kTotal) { 5740 } else if (name == HPhase::kTotal) {
5632 total_ += ticks; 5741 total_ += ticks;
5633 } else { 5742 } else {
5743 total_size_ += size;
5634 for (int i = 0; i < names_.length(); ++i) { 5744 for (int i = 0; i < names_.length(); ++i) {
5635 if (names_[i] == name) { 5745 if (names_[i] == name) {
5636 timing_[i] += ticks; 5746 timing_[i] += ticks;
5747 sizes_[i] += size;
5637 return; 5748 return;
5638 } 5749 }
5639 } 5750 }
5640 names_.Add(name); 5751 names_.Add(name);
5641 timing_.Add(ticks); 5752 timing_.Add(ticks);
5753 sizes_.Add(size);
5642 } 5754 }
5643 } 5755 }
5644 5756
5645 5757
5646 const char* const HPhase::kFullCodeGen = "Full code generator"; 5758 const char* const HPhase::kFullCodeGen = "Full code generator";
5647 const char* const HPhase::kTotal = "Total"; 5759 const char* const HPhase::kTotal = "Total";
5648 5760
5649 5761
5650 void HPhase::Begin(const char* name, 5762 void HPhase::Begin(const char* name,
5651 HGraph* graph, 5763 HGraph* graph,
5652 LChunk* chunk, 5764 LChunk* chunk,
5653 LAllocator* allocator) { 5765 LAllocator* allocator) {
5654 name_ = name; 5766 name_ = name;
5655 graph_ = graph; 5767 graph_ = graph;
5656 chunk_ = chunk; 5768 chunk_ = chunk;
5657 allocator_ = allocator; 5769 allocator_ = allocator;
5658 if (allocator != NULL && chunk_ == NULL) { 5770 if (allocator != NULL && chunk_ == NULL) {
5659 chunk_ = allocator->chunk(); 5771 chunk_ = allocator->chunk();
5660 } 5772 }
5661 if (FLAG_time_hydrogen) start_ = OS::Ticks(); 5773 if (FLAG_time_hydrogen) start_ = OS::Ticks();
5774 start_allocation_size_ = Zone::allocation_size_;
5662 } 5775 }
5663 5776
5664 5777
5665 void HPhase::End() const { 5778 void HPhase::End() const {
5666 if (FLAG_time_hydrogen) { 5779 if (FLAG_time_hydrogen) {
5667 int64_t end = OS::Ticks(); 5780 int64_t end = OS::Ticks();
5668 HStatistics::Instance()->SaveTiming(name_, end - start_); 5781 unsigned size = Zone::allocation_size_ - start_allocation_size_;
5782 HStatistics::Instance()->SaveTiming(name_, end - start_, size);
5669 } 5783 }
5670 5784
5671 if (FLAG_trace_hydrogen) { 5785 if (FLAG_trace_hydrogen) {
5672 if (graph_ != NULL) HTracer::Instance()->TraceHydrogen(name_, graph_); 5786 if (graph_ != NULL) HTracer::Instance()->TraceHydrogen(name_, graph_);
5673 if (chunk_ != NULL) HTracer::Instance()->TraceLithium(name_, chunk_); 5787 if (chunk_ != NULL) HTracer::Instance()->TraceLithium(name_, chunk_);
5674 if (allocator_ != NULL) { 5788 if (allocator_ != NULL) {
5675 HTracer::Instance()->TraceLiveRanges(name_, allocator_); 5789 HTracer::Instance()->TraceLiveRanges(name_, allocator_);
5676 } 5790 }
5677 } 5791 }
5678 5792
5679 #ifdef DEBUG 5793 #ifdef DEBUG
5680 if (graph_ != NULL) graph_->Verify(); 5794 if (graph_ != NULL) graph_->Verify();
5681 if (chunk_ != NULL) chunk_->Verify();
5682 if (allocator_ != NULL) allocator_->Verify(); 5795 if (allocator_ != NULL) allocator_->Verify();
5683 #endif 5796 #endif
5684 } 5797 }
5685 5798
5686 } } // namespace v8::internal 5799 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698