OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 |
(...skipping 3805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3816 | 3816 |
3817 | 3817 |
3818 #define CHECK_ALIVE(call) \ | 3818 #define CHECK_ALIVE(call) \ |
3819 do { \ | 3819 do { \ |
3820 call; \ | 3820 call; \ |
3821 if (HasStackOverflow() || current_block() == NULL) return; \ | 3821 if (HasStackOverflow() || current_block() == NULL) return; \ |
3822 } while (false) | 3822 } while (false) |
3823 | 3823 |
3824 | 3824 |
3825 void HOptimizedGraphBuilder::Bailout(const char* reason) { | 3825 void HOptimizedGraphBuilder::Bailout(const char* reason) { |
3826 info()->set_bailout_reason(reason); | 3826 current_info()->set_bailout_reason(reason); |
3827 SetStackOverflow(); | 3827 SetStackOverflow(); |
3828 } | 3828 } |
3829 | 3829 |
3830 | 3830 |
3831 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { | 3831 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { |
3832 EffectContext for_effect(this); | 3832 EffectContext for_effect(this); |
3833 Visit(expr); | 3833 Visit(expr); |
3834 } | 3834 } |
3835 | 3835 |
3836 | 3836 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3873 | 3873 |
3874 void HOptimizedGraphBuilder::VisitExpressions( | 3874 void HOptimizedGraphBuilder::VisitExpressions( |
3875 ZoneList<Expression*>* exprs) { | 3875 ZoneList<Expression*>* exprs) { |
3876 for (int i = 0; i < exprs->length(); ++i) { | 3876 for (int i = 0; i < exprs->length(); ++i) { |
3877 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 3877 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
3878 } | 3878 } |
3879 } | 3879 } |
3880 | 3880 |
3881 | 3881 |
3882 bool HOptimizedGraphBuilder::BuildGraph() { | 3882 bool HOptimizedGraphBuilder::BuildGraph() { |
3883 if (info()->function()->is_generator()) { | 3883 if (current_info()->function()->is_generator()) { |
3884 Bailout("function is a generator"); | 3884 Bailout("function is a generator"); |
3885 return false; | 3885 return false; |
3886 } | 3886 } |
3887 Scope* scope = info()->scope(); | 3887 Scope* scope = current_info()->scope(); |
3888 if (scope->HasIllegalRedeclaration()) { | 3888 if (scope->HasIllegalRedeclaration()) { |
3889 Bailout("function with illegal redeclaration"); | 3889 Bailout("function with illegal redeclaration"); |
3890 return false; | 3890 return false; |
3891 } | 3891 } |
3892 if (scope->calls_eval()) { | 3892 if (scope->calls_eval()) { |
3893 Bailout("function calls eval"); | 3893 Bailout("function calls eval"); |
3894 return false; | 3894 return false; |
3895 } | 3895 } |
3896 SetUpScope(scope); | 3896 SetUpScope(scope); |
3897 | 3897 |
(...skipping 23 matching lines...) Expand all Loading... |
3921 if (scope->is_function_scope() && scope->function() != NULL) { | 3921 if (scope->is_function_scope() && scope->function() != NULL) { |
3922 VisitVariableDeclaration(scope->function()); | 3922 VisitVariableDeclaration(scope->function()); |
3923 } | 3923 } |
3924 VisitDeclarations(scope->declarations()); | 3924 VisitDeclarations(scope->declarations()); |
3925 AddSimulate(BailoutId::Declarations()); | 3925 AddSimulate(BailoutId::Declarations()); |
3926 | 3926 |
3927 HValue* context = environment()->LookupContext(); | 3927 HValue* context = environment()->LookupContext(); |
3928 AddInstruction( | 3928 AddInstruction( |
3929 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); | 3929 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); |
3930 | 3930 |
3931 VisitStatements(info()->function()->body()); | 3931 VisitStatements(current_info()->function()->body()); |
3932 if (HasStackOverflow()) return false; | 3932 if (HasStackOverflow()) return false; |
3933 | 3933 |
3934 if (current_block() != NULL) { | 3934 if (current_block() != NULL) { |
3935 AddReturn(graph()->GetConstantUndefined()); | 3935 AddReturn(graph()->GetConstantUndefined()); |
3936 set_current_block(NULL); | 3936 set_current_block(NULL); |
3937 } | 3937 } |
3938 | 3938 |
3939 // If the checksum of the number of type info changes is the same as the | 3939 // If the checksum of the number of type info changes is the same as the |
3940 // last time this function was compiled, then this recompile is likely not | 3940 // last time this function was compiled, then this recompile is likely not |
3941 // due to missing/inadequate type feedback, but rather too aggressive | 3941 // due to missing/inadequate type feedback, but rather too aggressive |
3942 // optimization. Disable optimistic LICM in that case. | 3942 // optimization. Disable optimistic LICM in that case. |
3943 Handle<Code> unoptimized_code(info()->shared_info()->code()); | 3943 Handle<Code> unoptimized_code(current_info()->shared_info()->code()); |
3944 ASSERT(unoptimized_code->kind() == Code::FUNCTION); | 3944 ASSERT(unoptimized_code->kind() == Code::FUNCTION); |
3945 Handle<TypeFeedbackInfo> type_info( | 3945 Handle<TypeFeedbackInfo> type_info( |
3946 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); | 3946 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); |
3947 int checksum = type_info->own_type_change_checksum(); | 3947 int checksum = type_info->own_type_change_checksum(); |
3948 int composite_checksum = graph()->update_type_change_checksum(checksum); | 3948 int composite_checksum = graph()->update_type_change_checksum(checksum); |
3949 graph()->set_use_optimistic_licm( | 3949 graph()->set_use_optimistic_licm( |
3950 !type_info->matches_inlined_type_change_checksum(composite_checksum)); | 3950 !type_info->matches_inlined_type_change_checksum(composite_checksum)); |
3951 type_info->set_inlined_type_change_checksum(composite_checksum); | 3951 type_info->set_inlined_type_change_checksum(composite_checksum); |
3952 | 3952 |
3953 return true; | 3953 return true; |
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5122 } else { | 5122 } else { |
5123 if (fall_through_block != NULL) fall_through_block->Goto(break_block); | 5123 if (fall_through_block != NULL) fall_through_block->Goto(break_block); |
5124 if (last_block != NULL) last_block->Goto(break_block); | 5124 if (last_block != NULL) last_block->Goto(break_block); |
5125 break_block->SetJoinId(stmt->ExitId()); | 5125 break_block->SetJoinId(stmt->ExitId()); |
5126 set_current_block(break_block); | 5126 set_current_block(break_block); |
5127 } | 5127 } |
5128 } | 5128 } |
5129 | 5129 |
5130 | 5130 |
5131 bool HOptimizedGraphBuilder::HasOsrEntryAt(IterationStatement* statement) { | 5131 bool HOptimizedGraphBuilder::HasOsrEntryAt(IterationStatement* statement) { |
5132 return statement->OsrEntryId() == info()->osr_ast_id(); | 5132 return statement->OsrEntryId() == current_info()->osr_ast_id(); |
5133 } | 5133 } |
5134 | 5134 |
5135 | 5135 |
5136 bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { | 5136 bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { |
5137 if (!HasOsrEntryAt(statement)) return false; | 5137 if (!HasOsrEntryAt(statement)) return false; |
5138 | 5138 |
5139 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); | 5139 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); |
5140 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); | 5140 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); |
5141 HValue* true_value = graph()->GetConstantTrue(); | 5141 HValue* true_value = graph()->GetConstantTrue(); |
5142 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); | 5142 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5509 | 5509 |
5510 return Handle<SharedFunctionInfo>(); | 5510 return Handle<SharedFunctionInfo>(); |
5511 } | 5511 } |
5512 | 5512 |
5513 | 5513 |
5514 void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 5514 void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
5515 ASSERT(!HasStackOverflow()); | 5515 ASSERT(!HasStackOverflow()); |
5516 ASSERT(current_block() != NULL); | 5516 ASSERT(current_block() != NULL); |
5517 ASSERT(current_block()->HasPredecessor()); | 5517 ASSERT(current_block()->HasPredecessor()); |
5518 Handle<SharedFunctionInfo> shared_info = | 5518 Handle<SharedFunctionInfo> shared_info = |
5519 SearchSharedFunctionInfo(info()->shared_info()->code(), expr); | 5519 SearchSharedFunctionInfo(current_info()->shared_info()->code(), expr); |
5520 if (shared_info.is_null()) { | 5520 if (shared_info.is_null()) { |
5521 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); | 5521 shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script()); |
5522 } | 5522 } |
5523 // We also have a stack overflow if the recursive compilation did. | 5523 // We also have a stack overflow if the recursive compilation did. |
5524 if (HasStackOverflow()) return; | 5524 if (HasStackOverflow()) return; |
5525 HValue* context = environment()->LookupContext(); | 5525 HValue* context = environment()->LookupContext(); |
5526 HFunctionLiteral* instr = | 5526 HFunctionLiteral* instr = |
5527 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); | 5527 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); |
5528 return ast_context()->ReturnInstruction(instr, expr->id()); | 5528 return ast_context()->ReturnInstruction(instr, expr->id()); |
5529 } | 5529 } |
5530 | 5530 |
5531 | 5531 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5572 if (join != NULL && !ast_context()->IsEffect()) { | 5572 if (join != NULL && !ast_context()->IsEffect()) { |
5573 return ast_context()->ReturnValue(Pop()); | 5573 return ast_context()->ReturnValue(Pop()); |
5574 } | 5574 } |
5575 } | 5575 } |
5576 } | 5576 } |
5577 | 5577 |
5578 | 5578 |
5579 HOptimizedGraphBuilder::GlobalPropertyAccess | 5579 HOptimizedGraphBuilder::GlobalPropertyAccess |
5580 HOptimizedGraphBuilder::LookupGlobalProperty( | 5580 HOptimizedGraphBuilder::LookupGlobalProperty( |
5581 Variable* var, LookupResult* lookup, bool is_store) { | 5581 Variable* var, LookupResult* lookup, bool is_store) { |
5582 if (var->is_this() || !info()->has_global_object()) { | 5582 if (var->is_this() || !current_info()->has_global_object()) { |
5583 return kUseGeneric; | 5583 return kUseGeneric; |
5584 } | 5584 } |
5585 Handle<GlobalObject> global(info()->global_object()); | 5585 Handle<GlobalObject> global(current_info()->global_object()); |
5586 global->Lookup(*var->name(), lookup); | 5586 global->Lookup(*var->name(), lookup); |
5587 if (!lookup->IsNormal() || | 5587 if (!lookup->IsNormal() || |
5588 (is_store && lookup->IsReadOnly()) || | 5588 (is_store && lookup->IsReadOnly()) || |
5589 lookup->holder() != *global) { | 5589 lookup->holder() != *global) { |
5590 return kUseGeneric; | 5590 return kUseGeneric; |
5591 } | 5591 } |
5592 | 5592 |
5593 return kUseCell; | 5593 return kUseCell; |
5594 } | 5594 } |
5595 | 5595 |
5596 | 5596 |
5597 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { | 5597 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
5598 ASSERT(var->IsContextSlot()); | 5598 ASSERT(var->IsContextSlot()); |
5599 HValue* context = environment()->LookupContext(); | 5599 HValue* context = environment()->LookupContext(); |
5600 int length = info()->scope()->ContextChainLength(var->scope()); | 5600 int length = current_info()->scope()->ContextChainLength(var->scope()); |
5601 while (length-- > 0) { | 5601 while (length-- > 0) { |
5602 HInstruction* context_instruction = new(zone()) HOuterContext(context); | 5602 HInstruction* context_instruction = new(zone()) HOuterContext(context); |
5603 AddInstruction(context_instruction); | 5603 AddInstruction(context_instruction); |
5604 context = context_instruction; | 5604 context = context_instruction; |
5605 } | 5605 } |
5606 return context; | 5606 return context; |
5607 } | 5607 } |
5608 | 5608 |
5609 | 5609 |
5610 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 5610 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
(...skipping 15 matching lines...) Expand all Loading... |
5626 HConstant* instr = | 5626 HConstant* instr = |
5627 new(zone()) HConstant(constant_value, Representation::Tagged()); | 5627 new(zone()) HConstant(constant_value, Representation::Tagged()); |
5628 return ast_context()->ReturnInstruction(instr, expr->id()); | 5628 return ast_context()->ReturnInstruction(instr, expr->id()); |
5629 } | 5629 } |
5630 | 5630 |
5631 LookupResult lookup(isolate()); | 5631 LookupResult lookup(isolate()); |
5632 GlobalPropertyAccess type = | 5632 GlobalPropertyAccess type = |
5633 LookupGlobalProperty(variable, &lookup, false); | 5633 LookupGlobalProperty(variable, &lookup, false); |
5634 | 5634 |
5635 if (type == kUseCell && | 5635 if (type == kUseCell && |
5636 info()->global_object()->IsAccessCheckNeeded()) { | 5636 current_info()->global_object()->IsAccessCheckNeeded()) { |
5637 type = kUseGeneric; | 5637 type = kUseGeneric; |
5638 } | 5638 } |
5639 | 5639 |
5640 if (type == kUseCell) { | 5640 if (type == kUseCell) { |
5641 Handle<GlobalObject> global(info()->global_object()); | 5641 Handle<GlobalObject> global(current_info()->global_object()); |
5642 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 5642 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
5643 HLoadGlobalCell* instr = | 5643 HLoadGlobalCell* instr = |
5644 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); | 5644 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); |
5645 return ast_context()->ReturnInstruction(instr, expr->id()); | 5645 return ast_context()->ReturnInstruction(instr, expr->id()); |
5646 } else { | 5646 } else { |
5647 HValue* context = environment()->LookupContext(); | 5647 HValue* context = environment()->LookupContext(); |
5648 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 5648 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
5649 AddInstruction(global_object); | 5649 AddInstruction(global_object); |
5650 HLoadGlobalGeneric* instr = | 5650 HLoadGlobalGeneric* instr = |
5651 new(zone()) HLoadGlobalGeneric(context, | 5651 new(zone()) HLoadGlobalGeneric(context, |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6222 // Otherwise, find the top prototype. | 6222 // Otherwise, find the top prototype. |
6223 while (proto->GetPrototype(isolate())->IsJSObject()) { | 6223 while (proto->GetPrototype(isolate())->IsJSObject()) { |
6224 proto = proto->GetPrototype(isolate()); | 6224 proto = proto->GetPrototype(isolate()); |
6225 } | 6225 } |
6226 ASSERT(proto->GetPrototype(isolate())->IsNull()); | 6226 ASSERT(proto->GetPrototype(isolate())->IsNull()); |
6227 } | 6227 } |
6228 ASSERT(proto->IsJSObject()); | 6228 ASSERT(proto->IsJSObject()); |
6229 AddInstruction(new(zone()) HCheckPrototypeMaps( | 6229 AddInstruction(new(zone()) HCheckPrototypeMaps( |
6230 Handle<JSObject>(JSObject::cast(map->prototype())), | 6230 Handle<JSObject>(JSObject::cast(map->prototype())), |
6231 Handle<JSObject>(JSObject::cast(proto)), | 6231 Handle<JSObject>(JSObject::cast(proto)), |
6232 zone())); | 6232 zone(), |
| 6233 top_info())); |
6233 } | 6234 } |
6234 | 6235 |
6235 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); | 6236 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); |
6236 Representation representation = ComputeLoadStoreRepresentation(map, lookup); | 6237 Representation representation = ComputeLoadStoreRepresentation(map, lookup); |
6237 bool transition_to_field = lookup->IsTransitionToField(*map); | 6238 bool transition_to_field = lookup->IsTransitionToField(*map); |
6238 | 6239 |
6239 HStoreNamedField *instr; | 6240 HStoreNamedField *instr; |
6240 if (FLAG_track_double_fields && representation.IsDouble()) { | 6241 if (FLAG_track_double_fields && representation.IsDouble()) { |
6241 if (transition_to_field) { | 6242 if (transition_to_field) { |
6242 // The store requires a mutable HeapNumber to be allocated. | 6243 // The store requires a mutable HeapNumber to be allocated. |
(...skipping 15 matching lines...) Expand all Loading... |
6258 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); | 6259 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); |
6259 } | 6260 } |
6260 } else { | 6261 } else { |
6261 // This is a non-double store. | 6262 // This is a non-double store. |
6262 instr = new(zone()) HStoreNamedField( | 6263 instr = new(zone()) HStoreNamedField( |
6263 object, field_access, value, representation); | 6264 object, field_access, value, representation); |
6264 } | 6265 } |
6265 | 6266 |
6266 if (transition_to_field) { | 6267 if (transition_to_field) { |
6267 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); | 6268 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); |
6268 instr->set_transition(transition); | 6269 instr->SetTransition(transition, top_info()); |
6269 // TODO(fschneider): Record the new map type of the object in the IR to | 6270 // TODO(fschneider): Record the new map type of the object in the IR to |
6270 // enable elimination of redundant checks after the transition store. | 6271 // enable elimination of redundant checks after the transition store. |
6271 instr->SetGVNFlag(kChangesMaps); | 6272 instr->SetGVNFlag(kChangesMaps); |
6272 } | 6273 } |
6273 return instr; | 6274 return instr; |
6274 } | 6275 } |
6275 | 6276 |
6276 | 6277 |
6277 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric( | 6278 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric( |
6278 HValue* object, | 6279 HValue* object, |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6561 // superclass of Assignment and CountOperation, we cannot just pass the | 6562 // superclass of Assignment and CountOperation, we cannot just pass the |
6562 // owning expression instead of position and ast_id separately. | 6563 // owning expression instead of position and ast_id separately. |
6563 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 6564 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
6564 Variable* var, | 6565 Variable* var, |
6565 HValue* value, | 6566 HValue* value, |
6566 int position, | 6567 int position, |
6567 BailoutId ast_id) { | 6568 BailoutId ast_id) { |
6568 LookupResult lookup(isolate()); | 6569 LookupResult lookup(isolate()); |
6569 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 6570 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
6570 if (type == kUseCell) { | 6571 if (type == kUseCell) { |
6571 Handle<GlobalObject> global(info()->global_object()); | 6572 Handle<GlobalObject> global(current_info()->global_object()); |
6572 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 6573 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
6573 HInstruction* instr = | 6574 HInstruction* instr = |
6574 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 6575 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
6575 instr->set_position(position); | 6576 instr->set_position(position); |
6576 AddInstruction(instr); | 6577 AddInstruction(instr); |
6577 if (instr->HasObservableSideEffects()) { | 6578 if (instr->HasObservableSideEffects()) { |
6578 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 6579 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
6579 } | 6580 } |
6580 } else { | 6581 } else { |
6581 HValue* context = environment()->LookupContext(); | 6582 HValue* context = environment()->LookupContext(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6626 if (var->mode() == CONST) { | 6627 if (var->mode() == CONST) { |
6627 return Bailout("unsupported const compound assignment"); | 6628 return Bailout("unsupported const compound assignment"); |
6628 } | 6629 } |
6629 BindIfLive(var, Top()); | 6630 BindIfLive(var, Top()); |
6630 break; | 6631 break; |
6631 | 6632 |
6632 case Variable::CONTEXT: { | 6633 case Variable::CONTEXT: { |
6633 // Bail out if we try to mutate a parameter value in a function | 6634 // Bail out if we try to mutate a parameter value in a function |
6634 // using the arguments object. We do not (yet) correctly handle the | 6635 // using the arguments object. We do not (yet) correctly handle the |
6635 // arguments property of the function. | 6636 // arguments property of the function. |
6636 if (info()->scope()->arguments() != NULL) { | 6637 if (current_info()->scope()->arguments() != NULL) { |
6637 // Parameters will be allocated to context slots. We have no | 6638 // Parameters will be allocated to context slots. We have no |
6638 // direct way to detect that the variable is a parameter so we do | 6639 // direct way to detect that the variable is a parameter so we do |
6639 // a linear search of the parameter variables. | 6640 // a linear search of the parameter variables. |
6640 int count = info()->scope()->num_parameters(); | 6641 int count = current_info()->scope()->num_parameters(); |
6641 for (int i = 0; i < count; ++i) { | 6642 for (int i = 0; i < count; ++i) { |
6642 if (var == info()->scope()->parameter(i)) { | 6643 if (var == current_info()->scope()->parameter(i)) { |
6643 Bailout( | 6644 Bailout( |
6644 "assignment to parameter, function uses arguments object"); | 6645 "assignment to parameter, function uses arguments object"); |
6645 } | 6646 } |
6646 } | 6647 } |
6647 } | 6648 } |
6648 | 6649 |
6649 HStoreContextSlot::Mode mode; | 6650 HStoreContextSlot::Mode mode; |
6650 | 6651 |
6651 switch (var->mode()) { | 6652 switch (var->mode()) { |
6652 case LET: | 6653 case LET: |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6852 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); | 6853 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); |
6853 HValue* value = Pop(); | 6854 HValue* value = Pop(); |
6854 BindIfLive(var, value); | 6855 BindIfLive(var, value); |
6855 return ast_context()->ReturnValue(value); | 6856 return ast_context()->ReturnValue(value); |
6856 } | 6857 } |
6857 | 6858 |
6858 case Variable::CONTEXT: { | 6859 case Variable::CONTEXT: { |
6859 // Bail out if we try to mutate a parameter value in a function using | 6860 // Bail out if we try to mutate a parameter value in a function using |
6860 // the arguments object. We do not (yet) correctly handle the | 6861 // the arguments object. We do not (yet) correctly handle the |
6861 // arguments property of the function. | 6862 // arguments property of the function. |
6862 if (info()->scope()->arguments() != NULL) { | 6863 if (current_info()->scope()->arguments() != NULL) { |
6863 // Parameters will rewrite to context slots. We have no direct way | 6864 // Parameters will rewrite to context slots. We have no direct way |
6864 // to detect that the variable is a parameter. | 6865 // to detect that the variable is a parameter. |
6865 int count = info()->scope()->num_parameters(); | 6866 int count = current_info()->scope()->num_parameters(); |
6866 for (int i = 0; i < count; ++i) { | 6867 for (int i = 0; i < count; ++i) { |
6867 if (var == info()->scope()->parameter(i)) { | 6868 if (var == current_info()->scope()->parameter(i)) { |
6868 return Bailout("assignment to parameter in arguments object"); | 6869 return Bailout("assignment to parameter in arguments object"); |
6869 } | 6870 } |
6870 } | 6871 } |
6871 } | 6872 } |
6872 | 6873 |
6873 CHECK_ALIVE(VisitForValue(expr->value())); | 6874 CHECK_ALIVE(VisitForValue(expr->value())); |
6874 HStoreContextSlot::Mode mode; | 6875 HStoreContextSlot::Mode mode; |
6875 if (expr->op() == Token::ASSIGN) { | 6876 if (expr->op() == Token::ASSIGN) { |
6876 switch (var->mode()) { | 6877 switch (var->mode()) { |
6877 case LET: | 6878 case LET: |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7019 return new(zone()) HConstant(function, Representation::Tagged()); | 7020 return new(zone()) HConstant(function, Representation::Tagged()); |
7020 } | 7021 } |
7021 | 7022 |
7022 // Handle a load from a known field somewhere in the prototype chain. | 7023 // Handle a load from a known field somewhere in the prototype chain. |
7023 LookupInPrototypes(map, name, &lookup); | 7024 LookupInPrototypes(map, name, &lookup); |
7024 if (lookup.IsField()) { | 7025 if (lookup.IsField()) { |
7025 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 7026 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
7026 Handle<JSObject> holder(lookup.holder()); | 7027 Handle<JSObject> holder(lookup.holder()); |
7027 Handle<Map> holder_map(holder->map()); | 7028 Handle<Map> holder_map(holder->map()); |
7028 AddCheckMap(object, map); | 7029 AddCheckMap(object, map); |
7029 AddInstruction( | 7030 AddInstruction(new(zone()) HCheckPrototypeMaps( |
7030 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); | 7031 prototype, holder, zone(), top_info())); |
7031 HValue* holder_value = AddInstruction(new(zone()) | 7032 HValue* holder_value = AddInstruction(new(zone()) |
7032 HConstant(holder, Representation::Tagged())); | 7033 HConstant(holder, Representation::Tagged())); |
7033 return BuildLoadNamedField(holder_value, | 7034 return BuildLoadNamedField(holder_value, |
7034 HObjectAccess::ForField(holder_map, &lookup, name), | 7035 HObjectAccess::ForField(holder_map, &lookup, name), |
7035 ComputeLoadStoreRepresentation(map, &lookup)); | 7036 ComputeLoadStoreRepresentation(map, &lookup)); |
7036 } | 7037 } |
7037 | 7038 |
7038 // Handle a load of a constant function somewhere in the prototype chain. | 7039 // Handle a load of a constant function somewhere in the prototype chain. |
7039 if (lookup.IsConstantFunction()) { | 7040 if (lookup.IsConstantFunction()) { |
7040 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 7041 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
7041 Handle<JSObject> holder(lookup.holder()); | 7042 Handle<JSObject> holder(lookup.holder()); |
7042 Handle<Map> holder_map(holder->map()); | 7043 Handle<Map> holder_map(holder->map()); |
7043 AddCheckMap(object, map); | 7044 AddCheckMap(object, map); |
7044 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); | 7045 AddInstruction(new(zone()) HCheckPrototypeMaps( |
| 7046 prototype, holder, zone(), top_info())); |
7045 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); | 7047 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); |
7046 return new(zone()) HConstant(function, Representation::Tagged()); | 7048 return new(zone()) HConstant(function, Representation::Tagged()); |
7047 } | 7049 } |
7048 | 7050 |
7049 // No luck, do a generic load. | 7051 // No luck, do a generic load. |
7050 return BuildLoadNamedGeneric(object, name, expr); | 7052 return BuildLoadNamedGeneric(object, name, expr); |
7051 } | 7053 } |
7052 | 7054 |
7053 | 7055 |
7054 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 7056 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
(...skipping 16 matching lines...) Expand all Loading... |
7071 if (dependency) { | 7073 if (dependency) { |
7072 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 7074 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
7073 } | 7075 } |
7074 | 7076 |
7075 // Loads from a "stock" fast holey double arrays can elide the hole check. | 7077 // Loads from a "stock" fast holey double arrays can elide the hole check. |
7076 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; | 7078 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; |
7077 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && | 7079 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && |
7078 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | 7080 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
7079 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); | 7081 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); |
7080 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); | 7082 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); |
7081 AddInstruction( | 7083 AddInstruction(new(zone()) HCheckPrototypeMaps( |
7082 new(zone()) HCheckPrototypeMaps(prototype, object_prototype, zone())); | 7084 prototype, object_prototype, zone(), top_info())); |
7083 load_mode = ALLOW_RETURN_HOLE; | 7085 load_mode = ALLOW_RETURN_HOLE; |
7084 graph()->MarkDependsOnEmptyArrayProtoElements(); | 7086 graph()->MarkDependsOnEmptyArrayProtoElements(); |
7085 } | 7087 } |
7086 | 7088 |
7087 return BuildUncheckedMonomorphicElementAccess( | 7089 return BuildUncheckedMonomorphicElementAccess( |
7088 object, key, val, | 7090 object, key, val, |
7089 mapcheck, map->instance_type() == JS_ARRAY_TYPE, | 7091 mapcheck, map->instance_type() == JS_ARRAY_TYPE, |
7090 map->elements_kind(), is_store, load_mode, store_mode); | 7092 map->elements_kind(), is_store, load_mode, store_mode); |
7091 } | 7093 } |
7092 | 7094 |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7587 } | 7589 } |
7588 instr->set_position(expr->position()); | 7590 instr->set_position(expr->position()); |
7589 return ast_context()->ReturnInstruction(instr, expr->id()); | 7591 return ast_context()->ReturnInstruction(instr, expr->id()); |
7590 } | 7592 } |
7591 | 7593 |
7592 | 7594 |
7593 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, | 7595 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, |
7594 Handle<Map> receiver_map) { | 7596 Handle<Map> receiver_map) { |
7595 if (!holder.is_null()) { | 7597 if (!holder.is_null()) { |
7596 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); | 7598 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); |
7597 AddInstruction( | 7599 AddInstruction(new(zone()) HCheckPrototypeMaps( |
7598 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); | 7600 prototype, holder, zone(), top_info())); |
7599 } | 7601 } |
7600 } | 7602 } |
7601 | 7603 |
7602 | 7604 |
7603 void HOptimizedGraphBuilder::AddCheckConstantFunction( | 7605 void HOptimizedGraphBuilder::AddCheckConstantFunction( |
7604 Handle<JSObject> holder, | 7606 Handle<JSObject> holder, |
7605 HValue* receiver, | 7607 HValue* receiver, |
7606 Handle<Map> receiver_map) { | 7608 Handle<Map> receiver_map) { |
7607 // Constant functions have the nice property that the map will change if they | 7609 // Constant functions have the nice property that the map will change if they |
7608 // are overwritten. Therefore it is enough to check the map of the holder and | 7610 // are overwritten. Therefore it is enough to check the map of the holder and |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7733 if (expr->check_type() == NUMBER_CHECK) { | 7735 if (expr->check_type() == NUMBER_CHECK) { |
7734 if_true->Goto(number_block); | 7736 if_true->Goto(number_block); |
7735 if_true = number_block; | 7737 if_true = number_block; |
7736 number_block->SetJoinId(expr->id()); | 7738 number_block->SetJoinId(expr->id()); |
7737 } | 7739 } |
7738 set_current_block(if_true); | 7740 set_current_block(if_true); |
7739 | 7741 |
7740 expr->ComputeTarget(map, name); | 7742 expr->ComputeTarget(map, name); |
7741 AddCheckPrototypeMaps(expr->holder(), map); | 7743 AddCheckPrototypeMaps(expr->holder(), map); |
7742 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { | 7744 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { |
7743 Handle<JSFunction> caller = info()->closure(); | 7745 Handle<JSFunction> caller = current_info()->closure(); |
7744 SmartArrayPointer<char> caller_name = | 7746 SmartArrayPointer<char> caller_name = |
7745 caller->shared()->DebugName()->ToCString(); | 7747 caller->shared()->DebugName()->ToCString(); |
7746 PrintF("Trying to inline the polymorphic call to %s from %s\n", | 7748 PrintF("Trying to inline the polymorphic call to %s from %s\n", |
7747 *name->ToCString(), | 7749 *name->ToCString(), |
7748 *caller_name); | 7750 *caller_name); |
7749 } | 7751 } |
7750 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { | 7752 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { |
7751 // Trying to inline will signal that we should bailout from the | 7753 // Trying to inline will signal that we should bailout from the |
7752 // entire compilation by setting stack overflow on the visitor. | 7754 // entire compilation by setting stack overflow on the visitor. |
7753 if (HasStackOverflow()) return; | 7755 if (HasStackOverflow()) return; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7817 | 7819 |
7818 | 7820 |
7819 static const int kNotInlinable = 1000000000; | 7821 static const int kNotInlinable = 1000000000; |
7820 | 7822 |
7821 | 7823 |
7822 int HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) { | 7824 int HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) { |
7823 if (!FLAG_use_inlining) return kNotInlinable; | 7825 if (!FLAG_use_inlining) return kNotInlinable; |
7824 | 7826 |
7825 // Precondition: call is monomorphic and we have found a target with the | 7827 // Precondition: call is monomorphic and we have found a target with the |
7826 // appropriate arity. | 7828 // appropriate arity. |
7827 Handle<JSFunction> caller = info()->closure(); | 7829 Handle<JSFunction> caller = current_info()->closure(); |
7828 Handle<SharedFunctionInfo> target_shared(target->shared()); | 7830 Handle<SharedFunctionInfo> target_shared(target->shared()); |
7829 | 7831 |
7830 // Do a quick check on source code length to avoid parsing large | 7832 // Do a quick check on source code length to avoid parsing large |
7831 // inlining candidates. | 7833 // inlining candidates. |
7832 if (target_shared->SourceSize() > | 7834 if (target_shared->SourceSize() > |
7833 Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) { | 7835 Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) { |
7834 TraceInline(target, caller, "target text too big"); | 7836 TraceInline(target, caller, "target text too big"); |
7835 return kNotInlinable; | 7837 return kNotInlinable; |
7836 } | 7838 } |
7837 | 7839 |
(...skipping 15 matching lines...) Expand all Loading... |
7853 bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, | 7855 bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, |
7854 Handle<JSFunction> target, | 7856 Handle<JSFunction> target, |
7855 int arguments_count, | 7857 int arguments_count, |
7856 HValue* implicit_return_value, | 7858 HValue* implicit_return_value, |
7857 BailoutId ast_id, | 7859 BailoutId ast_id, |
7858 BailoutId return_id, | 7860 BailoutId return_id, |
7859 InliningKind inlining_kind) { | 7861 InliningKind inlining_kind) { |
7860 int nodes_added = InliningAstSize(target); | 7862 int nodes_added = InliningAstSize(target); |
7861 if (nodes_added == kNotInlinable) return false; | 7863 if (nodes_added == kNotInlinable) return false; |
7862 | 7864 |
7863 Handle<JSFunction> caller = info()->closure(); | 7865 Handle<JSFunction> caller = current_info()->closure(); |
7864 | 7866 |
7865 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { | 7867 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { |
7866 TraceInline(target, caller, "target AST is too large [early]"); | 7868 TraceInline(target, caller, "target AST is too large [early]"); |
7867 return false; | 7869 return false; |
7868 } | 7870 } |
7869 | 7871 |
7870 #if !defined(V8_TARGET_ARCH_IA32) | 7872 #if !defined(V8_TARGET_ARCH_IA32) |
7871 // Target must be able to use caller's context. | 7873 // Target must be able to use caller's context. |
7872 CompilationInfo* outer_info = info(); | 7874 CompilationInfo* outer_info = current_info(); |
7873 if (target->context() != outer_info->closure()->context() || | 7875 if (target->context() != outer_info->closure()->context() || |
7874 outer_info->scope()->contains_with() || | 7876 outer_info->scope()->contains_with() || |
7875 outer_info->scope()->num_heap_slots() > 0) { | 7877 outer_info->scope()->num_heap_slots() > 0) { |
7876 TraceInline(target, caller, "target requires context change"); | 7878 TraceInline(target, caller, "target requires context change"); |
7877 return false; | 7879 return false; |
7878 } | 7880 } |
7879 #endif | 7881 #endif |
7880 | 7882 |
7881 | 7883 |
7882 // Don't inline deeper than kMaxInliningLevels calls. | 7884 // Don't inline deeper than kMaxInliningLevels calls. |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8297 case kStringCharAt: | 8299 case kStringCharAt: |
8298 if (argument_count == 2 && check_type == STRING_CHECK) { | 8300 if (argument_count == 2 && check_type == STRING_CHECK) { |
8299 HValue* index = Pop(); | 8301 HValue* index = Pop(); |
8300 HValue* string = Pop(); | 8302 HValue* string = Pop(); |
8301 HValue* context = environment()->LookupContext(); | 8303 HValue* context = environment()->LookupContext(); |
8302 ASSERT(!expr->holder().is_null()); | 8304 ASSERT(!expr->holder().is_null()); |
8303 AddInstruction(new(zone()) HCheckPrototypeMaps( | 8305 AddInstruction(new(zone()) HCheckPrototypeMaps( |
8304 Call::GetPrototypeForPrimitiveCheck(STRING_CHECK, | 8306 Call::GetPrototypeForPrimitiveCheck(STRING_CHECK, |
8305 expr->holder()->GetIsolate()), | 8307 expr->holder()->GetIsolate()), |
8306 expr->holder(), | 8308 expr->holder(), |
8307 zone())); | 8309 zone(), |
| 8310 top_info())); |
8308 HInstruction* char_code = | 8311 HInstruction* char_code = |
8309 BuildStringCharCodeAt(context, string, index); | 8312 BuildStringCharCodeAt(context, string, index); |
8310 if (id == kStringCharCodeAt) { | 8313 if (id == kStringCharCodeAt) { |
8311 ast_context()->ReturnInstruction(char_code, expr->id()); | 8314 ast_context()->ReturnInstruction(char_code, expr->id()); |
8312 return true; | 8315 return true; |
8313 } | 8316 } |
8314 AddInstruction(char_code); | 8317 AddInstruction(char_code); |
8315 HInstruction* result = | 8318 HInstruction* result = |
8316 HStringCharFromCode::New(zone(), context, char_code); | 8319 HStringCharFromCode::New(zone(), context, char_code); |
8317 ast_context()->ReturnInstruction(result, expr->id()); | 8320 ast_context()->ReturnInstruction(result, expr->id()); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8448 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) { | 8451 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) { |
8449 return false; | 8452 return false; |
8450 } | 8453 } |
8451 Handle<Map> function_map = expr->GetReceiverTypes()->first(); | 8454 Handle<Map> function_map = expr->GetReceiverTypes()->first(); |
8452 if (function_map->instance_type() != JS_FUNCTION_TYPE || | 8455 if (function_map->instance_type() != JS_FUNCTION_TYPE || |
8453 !expr->target()->shared()->HasBuiltinFunctionId() || | 8456 !expr->target()->shared()->HasBuiltinFunctionId() || |
8454 expr->target()->shared()->builtin_function_id() != kFunctionApply) { | 8457 expr->target()->shared()->builtin_function_id() != kFunctionApply) { |
8455 return false; | 8458 return false; |
8456 } | 8459 } |
8457 | 8460 |
8458 if (info()->scope()->arguments() == NULL) return false; | 8461 if (current_info()->scope()->arguments() == NULL) return false; |
8459 | 8462 |
8460 ZoneList<Expression*>* args = expr->arguments(); | 8463 ZoneList<Expression*>* args = expr->arguments(); |
8461 if (args->length() != 2) return false; | 8464 if (args->length() != 2) return false; |
8462 | 8465 |
8463 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); | 8466 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); |
8464 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; | 8467 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; |
8465 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); | 8468 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); |
8466 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; | 8469 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; |
8467 | 8470 |
8468 // Found pattern f.apply(receiver, arguments). | 8471 // Found pattern f.apply(receiver, arguments). |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8689 | 8692 |
8690 if (global_call) { | 8693 if (global_call) { |
8691 Variable* var = proxy->var(); | 8694 Variable* var = proxy->var(); |
8692 bool known_global_function = false; | 8695 bool known_global_function = false; |
8693 // If there is a global property cell for the name at compile time and | 8696 // If there is a global property cell for the name at compile time and |
8694 // access check is not enabled we assume that the function will not change | 8697 // access check is not enabled we assume that the function will not change |
8695 // and generate optimized code for calling the function. | 8698 // and generate optimized code for calling the function. |
8696 LookupResult lookup(isolate()); | 8699 LookupResult lookup(isolate()); |
8697 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); | 8700 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); |
8698 if (type == kUseCell && | 8701 if (type == kUseCell && |
8699 !info()->global_object()->IsAccessCheckNeeded()) { | 8702 !current_info()->global_object()->IsAccessCheckNeeded()) { |
8700 Handle<GlobalObject> global(info()->global_object()); | 8703 Handle<GlobalObject> global(current_info()->global_object()); |
8701 known_global_function = expr->ComputeGlobalTarget(global, &lookup); | 8704 known_global_function = expr->ComputeGlobalTarget(global, &lookup); |
8702 } | 8705 } |
8703 if (known_global_function) { | 8706 if (known_global_function) { |
8704 // Push the global object instead of the global receiver because | 8707 // Push the global object instead of the global receiver because |
8705 // code generated by the full code generator expects it. | 8708 // code generated by the full code generator expects it. |
8706 HValue* context = environment()->LookupContext(); | 8709 HValue* context = environment()->LookupContext(); |
8707 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 8710 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
8708 PushAndAdd(global_object); | 8711 PushAndAdd(global_object); |
8709 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8712 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
8710 | 8713 |
(...skipping 14 matching lines...) Expand all Loading... |
8725 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. | 8728 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. |
8726 if (FLAG_trace_inlining) { | 8729 if (FLAG_trace_inlining) { |
8727 PrintF("Inlining builtin "); | 8730 PrintF("Inlining builtin "); |
8728 expr->target()->ShortPrint(); | 8731 expr->target()->ShortPrint(); |
8729 PrintF("\n"); | 8732 PrintF("\n"); |
8730 } | 8733 } |
8731 return; | 8734 return; |
8732 } | 8735 } |
8733 if (TryInlineCall(expr)) return; | 8736 if (TryInlineCall(expr)) return; |
8734 | 8737 |
8735 if (expr->target().is_identical_to(info()->closure())) { | 8738 if (expr->target().is_identical_to(current_info()->closure())) { |
8736 graph()->MarkRecursive(); | 8739 graph()->MarkRecursive(); |
8737 } | 8740 } |
8738 | 8741 |
8739 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), | 8742 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), |
8740 argument_count)); | 8743 argument_count)); |
8741 } else { | 8744 } else { |
8742 HValue* context = environment()->LookupContext(); | 8745 HValue* context = environment()->LookupContext(); |
8743 HGlobalObject* receiver = new(zone()) HGlobalObject(context); | 8746 HGlobalObject* receiver = new(zone()) HGlobalObject(context); |
8744 AddInstruction(receiver); | 8747 AddInstruction(receiver); |
8745 PushAndAdd(new(zone()) HPushArgument(receiver)); | 8748 PushAndAdd(new(zone()) HPushArgument(receiver)); |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9224 | 9227 |
9225 case Variable::PARAMETER: | 9228 case Variable::PARAMETER: |
9226 case Variable::LOCAL: | 9229 case Variable::LOCAL: |
9227 BindIfLive(var, after); | 9230 BindIfLive(var, after); |
9228 break; | 9231 break; |
9229 | 9232 |
9230 case Variable::CONTEXT: { | 9233 case Variable::CONTEXT: { |
9231 // Bail out if we try to mutate a parameter value in a function | 9234 // Bail out if we try to mutate a parameter value in a function |
9232 // using the arguments object. We do not (yet) correctly handle the | 9235 // using the arguments object. We do not (yet) correctly handle the |
9233 // arguments property of the function. | 9236 // arguments property of the function. |
9234 if (info()->scope()->arguments() != NULL) { | 9237 if (current_info()->scope()->arguments() != NULL) { |
9235 // Parameters will rewrite to context slots. We have no direct | 9238 // Parameters will rewrite to context slots. We have no direct |
9236 // way to detect that the variable is a parameter so we use a | 9239 // way to detect that the variable is a parameter so we use a |
9237 // linear search of the parameter list. | 9240 // linear search of the parameter list. |
9238 int count = info()->scope()->num_parameters(); | 9241 int count = current_info()->scope()->num_parameters(); |
9239 for (int i = 0; i < count; ++i) { | 9242 for (int i = 0; i < count; ++i) { |
9240 if (var == info()->scope()->parameter(i)) { | 9243 if (var == current_info()->scope()->parameter(i)) { |
9241 return Bailout("assignment to parameter in arguments object"); | 9244 return Bailout("assignment to parameter in arguments object"); |
9242 } | 9245 } |
9243 } | 9246 } |
9244 } | 9247 } |
9245 | 9248 |
9246 HValue* context = BuildContextChainWalk(var); | 9249 HValue* context = BuildContextChainWalk(var); |
9247 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) | 9250 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) |
9248 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; | 9251 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; |
9249 HStoreContextSlot* instr = | 9252 HStoreContextSlot* instr = |
9250 new(zone()) HStoreContextSlot(context, var->index(), mode, after); | 9253 new(zone()) HStoreContextSlot(context, var->index(), mode, after); |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9829 } | 9832 } |
9830 | 9833 |
9831 if (op == Token::INSTANCEOF) { | 9834 if (op == Token::INSTANCEOF) { |
9832 // Check to see if the rhs of the instanceof is a global function not | 9835 // Check to see if the rhs of the instanceof is a global function not |
9833 // residing in new space. If it is we assume that the function will stay the | 9836 // residing in new space. If it is we assume that the function will stay the |
9834 // same. | 9837 // same. |
9835 Handle<JSFunction> target = Handle<JSFunction>::null(); | 9838 Handle<JSFunction> target = Handle<JSFunction>::null(); |
9836 VariableProxy* proxy = expr->right()->AsVariableProxy(); | 9839 VariableProxy* proxy = expr->right()->AsVariableProxy(); |
9837 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); | 9840 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); |
9838 if (global_function && | 9841 if (global_function && |
9839 info()->has_global_object() && | 9842 current_info()->has_global_object() && |
9840 !info()->global_object()->IsAccessCheckNeeded()) { | 9843 !current_info()->global_object()->IsAccessCheckNeeded()) { |
9841 Handle<String> name = proxy->name(); | 9844 Handle<String> name = proxy->name(); |
9842 Handle<GlobalObject> global(info()->global_object()); | 9845 Handle<GlobalObject> global(current_info()->global_object()); |
9843 LookupResult lookup(isolate()); | 9846 LookupResult lookup(isolate()); |
9844 global->Lookup(*name, &lookup); | 9847 global->Lookup(*name, &lookup); |
9845 if (lookup.IsNormal() && lookup.GetValue()->IsJSFunction()) { | 9848 if (lookup.IsNormal() && lookup.GetValue()->IsJSFunction()) { |
9846 Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue())); | 9849 Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue())); |
9847 // If the function is in new space we assume it's more likely to | 9850 // If the function is in new space we assume it's more likely to |
9848 // change and thus prefer the general IC code. | 9851 // change and thus prefer the general IC code. |
9849 if (!isolate()->heap()->InNewSpace(*candidate)) { | 9852 if (!isolate()->heap()->InNewSpace(*candidate)) { |
9850 target = candidate; | 9853 target = candidate; |
9851 } | 9854 } |
9852 } | 9855 } |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10275 | 10278 |
10276 | 10279 |
10277 void HOptimizedGraphBuilder::VisitDeclarations( | 10280 void HOptimizedGraphBuilder::VisitDeclarations( |
10278 ZoneList<Declaration*>* declarations) { | 10281 ZoneList<Declaration*>* declarations) { |
10279 ASSERT(globals_.is_empty()); | 10282 ASSERT(globals_.is_empty()); |
10280 AstVisitor::VisitDeclarations(declarations); | 10283 AstVisitor::VisitDeclarations(declarations); |
10281 if (!globals_.is_empty()) { | 10284 if (!globals_.is_empty()) { |
10282 Handle<FixedArray> array = | 10285 Handle<FixedArray> array = |
10283 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); | 10286 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); |
10284 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); | 10287 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); |
10285 int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | | 10288 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | |
10286 DeclareGlobalsNativeFlag::encode(info()->is_native()) | | 10289 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | |
10287 DeclareGlobalsLanguageMode::encode(info()->language_mode()); | 10290 DeclareGlobalsLanguageMode::encode(current_info()->language_mode()); |
10288 HInstruction* result = new(zone()) HDeclareGlobals( | 10291 HInstruction* result = new(zone()) HDeclareGlobals( |
10289 environment()->LookupContext(), array, flags); | 10292 environment()->LookupContext(), array, flags); |
10290 AddInstruction(result); | 10293 AddInstruction(result); |
10291 globals_.Clear(); | 10294 globals_.Clear(); |
10292 } | 10295 } |
10293 } | 10296 } |
10294 | 10297 |
10295 | 10298 |
10296 void HOptimizedGraphBuilder::VisitVariableDeclaration( | 10299 void HOptimizedGraphBuilder::VisitVariableDeclaration( |
10297 VariableDeclaration* declaration) { | 10300 VariableDeclaration* declaration) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10331 } | 10334 } |
10332 | 10335 |
10333 | 10336 |
10334 void HOptimizedGraphBuilder::VisitFunctionDeclaration( | 10337 void HOptimizedGraphBuilder::VisitFunctionDeclaration( |
10335 FunctionDeclaration* declaration) { | 10338 FunctionDeclaration* declaration) { |
10336 VariableProxy* proxy = declaration->proxy(); | 10339 VariableProxy* proxy = declaration->proxy(); |
10337 Variable* variable = proxy->var(); | 10340 Variable* variable = proxy->var(); |
10338 switch (variable->location()) { | 10341 switch (variable->location()) { |
10339 case Variable::UNALLOCATED: { | 10342 case Variable::UNALLOCATED: { |
10340 globals_.Add(variable->name(), zone()); | 10343 globals_.Add(variable->name(), zone()); |
10341 Handle<SharedFunctionInfo> function = | 10344 Handle<SharedFunctionInfo> function = Compiler::BuildFunctionInfo( |
10342 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); | 10345 declaration->fun(), current_info()->script()); |
10343 // Check for stack-overflow exception. | 10346 // Check for stack-overflow exception. |
10344 if (function.is_null()) return SetStackOverflow(); | 10347 if (function.is_null()) return SetStackOverflow(); |
10345 globals_.Add(function, zone()); | 10348 globals_.Add(function, zone()); |
10346 return; | 10349 return; |
10347 } | 10350 } |
10348 case Variable::PARAMETER: | 10351 case Variable::PARAMETER: |
10349 case Variable::LOCAL: { | 10352 case Variable::LOCAL: { |
10350 CHECK_ALIVE(VisitForValue(declaration->fun())); | 10353 CHECK_ALIVE(VisitForValue(declaration->fun())); |
10351 HValue* value = Pop(); | 10354 HValue* value = Pop(); |
10352 BindIfLive(variable, value); | 10355 BindIfLive(variable, value); |
(...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11613 } | 11616 } |
11614 } | 11617 } |
11615 | 11618 |
11616 #ifdef DEBUG | 11619 #ifdef DEBUG |
11617 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11620 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11618 if (allocator_ != NULL) allocator_->Verify(); | 11621 if (allocator_ != NULL) allocator_->Verify(); |
11619 #endif | 11622 #endif |
11620 } | 11623 } |
11621 | 11624 |
11622 } } // namespace v8::internal | 11625 } } // namespace v8::internal |
OLD | NEW |