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 3793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3804 | 3804 |
3805 | 3805 |
3806 #define CHECK_ALIVE(call) \ | 3806 #define CHECK_ALIVE(call) \ |
3807 do { \ | 3807 do { \ |
3808 call; \ | 3808 call; \ |
3809 if (HasStackOverflow() || current_block() == NULL) return; \ | 3809 if (HasStackOverflow() || current_block() == NULL) return; \ |
3810 } while (false) | 3810 } while (false) |
3811 | 3811 |
3812 | 3812 |
3813 void HOptimizedGraphBuilder::Bailout(const char* reason) { | 3813 void HOptimizedGraphBuilder::Bailout(const char* reason) { |
3814 info()->set_bailout_reason(reason); | 3814 current_info()->set_bailout_reason(reason); |
3815 SetStackOverflow(); | 3815 SetStackOverflow(); |
3816 } | 3816 } |
3817 | 3817 |
3818 | 3818 |
3819 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { | 3819 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { |
3820 EffectContext for_effect(this); | 3820 EffectContext for_effect(this); |
3821 Visit(expr); | 3821 Visit(expr); |
3822 } | 3822 } |
3823 | 3823 |
3824 | 3824 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3861 | 3861 |
3862 void HOptimizedGraphBuilder::VisitExpressions( | 3862 void HOptimizedGraphBuilder::VisitExpressions( |
3863 ZoneList<Expression*>* exprs) { | 3863 ZoneList<Expression*>* exprs) { |
3864 for (int i = 0; i < exprs->length(); ++i) { | 3864 for (int i = 0; i < exprs->length(); ++i) { |
3865 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 3865 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
3866 } | 3866 } |
3867 } | 3867 } |
3868 | 3868 |
3869 | 3869 |
3870 bool HOptimizedGraphBuilder::BuildGraph() { | 3870 bool HOptimizedGraphBuilder::BuildGraph() { |
3871 if (info()->function()->is_generator()) { | 3871 if (current_info()->function()->is_generator()) { |
3872 Bailout("function is a generator"); | 3872 Bailout("function is a generator"); |
3873 return false; | 3873 return false; |
3874 } | 3874 } |
3875 Scope* scope = info()->scope(); | 3875 Scope* scope = current_info()->scope(); |
3876 if (scope->HasIllegalRedeclaration()) { | 3876 if (scope->HasIllegalRedeclaration()) { |
3877 Bailout("function with illegal redeclaration"); | 3877 Bailout("function with illegal redeclaration"); |
3878 return false; | 3878 return false; |
3879 } | 3879 } |
3880 if (scope->calls_eval()) { | 3880 if (scope->calls_eval()) { |
3881 Bailout("function calls eval"); | 3881 Bailout("function calls eval"); |
3882 return false; | 3882 return false; |
3883 } | 3883 } |
3884 SetUpScope(scope); | 3884 SetUpScope(scope); |
3885 | 3885 |
(...skipping 23 matching lines...) Expand all Loading... |
3909 if (scope->is_function_scope() && scope->function() != NULL) { | 3909 if (scope->is_function_scope() && scope->function() != NULL) { |
3910 VisitVariableDeclaration(scope->function()); | 3910 VisitVariableDeclaration(scope->function()); |
3911 } | 3911 } |
3912 VisitDeclarations(scope->declarations()); | 3912 VisitDeclarations(scope->declarations()); |
3913 AddSimulate(BailoutId::Declarations()); | 3913 AddSimulate(BailoutId::Declarations()); |
3914 | 3914 |
3915 HValue* context = environment()->LookupContext(); | 3915 HValue* context = environment()->LookupContext(); |
3916 AddInstruction( | 3916 AddInstruction( |
3917 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); | 3917 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); |
3918 | 3918 |
3919 VisitStatements(info()->function()->body()); | 3919 VisitStatements(current_info()->function()->body()); |
3920 if (HasStackOverflow()) return false; | 3920 if (HasStackOverflow()) return false; |
3921 | 3921 |
3922 if (current_block() != NULL) { | 3922 if (current_block() != NULL) { |
3923 AddReturn(graph()->GetConstantUndefined()); | 3923 AddReturn(graph()->GetConstantUndefined()); |
3924 set_current_block(NULL); | 3924 set_current_block(NULL); |
3925 } | 3925 } |
3926 | 3926 |
3927 // If the checksum of the number of type info changes is the same as the | 3927 // If the checksum of the number of type info changes is the same as the |
3928 // last time this function was compiled, then this recompile is likely not | 3928 // last time this function was compiled, then this recompile is likely not |
3929 // due to missing/inadequate type feedback, but rather too aggressive | 3929 // due to missing/inadequate type feedback, but rather too aggressive |
3930 // optimization. Disable optimistic LICM in that case. | 3930 // optimization. Disable optimistic LICM in that case. |
3931 Handle<Code> unoptimized_code(info()->shared_info()->code()); | 3931 Handle<Code> unoptimized_code(current_info()->shared_info()->code()); |
3932 ASSERT(unoptimized_code->kind() == Code::FUNCTION); | 3932 ASSERT(unoptimized_code->kind() == Code::FUNCTION); |
3933 Handle<TypeFeedbackInfo> type_info( | 3933 Handle<TypeFeedbackInfo> type_info( |
3934 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); | 3934 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); |
3935 int checksum = type_info->own_type_change_checksum(); | 3935 int checksum = type_info->own_type_change_checksum(); |
3936 int composite_checksum = graph()->update_type_change_checksum(checksum); | 3936 int composite_checksum = graph()->update_type_change_checksum(checksum); |
3937 graph()->set_use_optimistic_licm( | 3937 graph()->set_use_optimistic_licm( |
3938 !type_info->matches_inlined_type_change_checksum(composite_checksum)); | 3938 !type_info->matches_inlined_type_change_checksum(composite_checksum)); |
3939 type_info->set_inlined_type_change_checksum(composite_checksum); | 3939 type_info->set_inlined_type_change_checksum(composite_checksum); |
3940 | 3940 |
3941 return true; | 3941 return true; |
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5110 } else { | 5110 } else { |
5111 if (fall_through_block != NULL) fall_through_block->Goto(break_block); | 5111 if (fall_through_block != NULL) fall_through_block->Goto(break_block); |
5112 if (last_block != NULL) last_block->Goto(break_block); | 5112 if (last_block != NULL) last_block->Goto(break_block); |
5113 break_block->SetJoinId(stmt->ExitId()); | 5113 break_block->SetJoinId(stmt->ExitId()); |
5114 set_current_block(break_block); | 5114 set_current_block(break_block); |
5115 } | 5115 } |
5116 } | 5116 } |
5117 | 5117 |
5118 | 5118 |
5119 bool HOptimizedGraphBuilder::HasOsrEntryAt(IterationStatement* statement) { | 5119 bool HOptimizedGraphBuilder::HasOsrEntryAt(IterationStatement* statement) { |
5120 return statement->OsrEntryId() == info()->osr_ast_id(); | 5120 return statement->OsrEntryId() == current_info()->osr_ast_id(); |
5121 } | 5121 } |
5122 | 5122 |
5123 | 5123 |
5124 bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { | 5124 bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { |
5125 if (!HasOsrEntryAt(statement)) return false; | 5125 if (!HasOsrEntryAt(statement)) return false; |
5126 | 5126 |
5127 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); | 5127 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); |
5128 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); | 5128 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); |
5129 HValue* true_value = graph()->GetConstantTrue(); | 5129 HValue* true_value = graph()->GetConstantTrue(); |
5130 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); | 5130 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... |
5497 | 5497 |
5498 return Handle<SharedFunctionInfo>(); | 5498 return Handle<SharedFunctionInfo>(); |
5499 } | 5499 } |
5500 | 5500 |
5501 | 5501 |
5502 void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 5502 void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
5503 ASSERT(!HasStackOverflow()); | 5503 ASSERT(!HasStackOverflow()); |
5504 ASSERT(current_block() != NULL); | 5504 ASSERT(current_block() != NULL); |
5505 ASSERT(current_block()->HasPredecessor()); | 5505 ASSERT(current_block()->HasPredecessor()); |
5506 Handle<SharedFunctionInfo> shared_info = | 5506 Handle<SharedFunctionInfo> shared_info = |
5507 SearchSharedFunctionInfo(info()->shared_info()->code(), expr); | 5507 SearchSharedFunctionInfo(current_info()->shared_info()->code(), expr); |
5508 if (shared_info.is_null()) { | 5508 if (shared_info.is_null()) { |
5509 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); | 5509 shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script()); |
5510 } | 5510 } |
5511 // We also have a stack overflow if the recursive compilation did. | 5511 // We also have a stack overflow if the recursive compilation did. |
5512 if (HasStackOverflow()) return; | 5512 if (HasStackOverflow()) return; |
5513 HValue* context = environment()->LookupContext(); | 5513 HValue* context = environment()->LookupContext(); |
5514 HFunctionLiteral* instr = | 5514 HFunctionLiteral* instr = |
5515 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); | 5515 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); |
5516 return ast_context()->ReturnInstruction(instr, expr->id()); | 5516 return ast_context()->ReturnInstruction(instr, expr->id()); |
5517 } | 5517 } |
5518 | 5518 |
5519 | 5519 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5560 if (join != NULL && !ast_context()->IsEffect()) { | 5560 if (join != NULL && !ast_context()->IsEffect()) { |
5561 return ast_context()->ReturnValue(Pop()); | 5561 return ast_context()->ReturnValue(Pop()); |
5562 } | 5562 } |
5563 } | 5563 } |
5564 } | 5564 } |
5565 | 5565 |
5566 | 5566 |
5567 HOptimizedGraphBuilder::GlobalPropertyAccess | 5567 HOptimizedGraphBuilder::GlobalPropertyAccess |
5568 HOptimizedGraphBuilder::LookupGlobalProperty( | 5568 HOptimizedGraphBuilder::LookupGlobalProperty( |
5569 Variable* var, LookupResult* lookup, bool is_store) { | 5569 Variable* var, LookupResult* lookup, bool is_store) { |
5570 if (var->is_this() || !info()->has_global_object()) { | 5570 if (var->is_this() || !current_info()->has_global_object()) { |
5571 return kUseGeneric; | 5571 return kUseGeneric; |
5572 } | 5572 } |
5573 Handle<GlobalObject> global(info()->global_object()); | 5573 Handle<GlobalObject> global(current_info()->global_object()); |
5574 global->Lookup(*var->name(), lookup); | 5574 global->Lookup(*var->name(), lookup); |
5575 if (!lookup->IsNormal() || | 5575 if (!lookup->IsNormal() || |
5576 (is_store && lookup->IsReadOnly()) || | 5576 (is_store && lookup->IsReadOnly()) || |
5577 lookup->holder() != *global) { | 5577 lookup->holder() != *global) { |
5578 return kUseGeneric; | 5578 return kUseGeneric; |
5579 } | 5579 } |
5580 | 5580 |
5581 return kUseCell; | 5581 return kUseCell; |
5582 } | 5582 } |
5583 | 5583 |
5584 | 5584 |
5585 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { | 5585 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
5586 ASSERT(var->IsContextSlot()); | 5586 ASSERT(var->IsContextSlot()); |
5587 HValue* context = environment()->LookupContext(); | 5587 HValue* context = environment()->LookupContext(); |
5588 int length = info()->scope()->ContextChainLength(var->scope()); | 5588 int length = current_info()->scope()->ContextChainLength(var->scope()); |
5589 while (length-- > 0) { | 5589 while (length-- > 0) { |
5590 HInstruction* context_instruction = new(zone()) HOuterContext(context); | 5590 HInstruction* context_instruction = new(zone()) HOuterContext(context); |
5591 AddInstruction(context_instruction); | 5591 AddInstruction(context_instruction); |
5592 context = context_instruction; | 5592 context = context_instruction; |
5593 } | 5593 } |
5594 return context; | 5594 return context; |
5595 } | 5595 } |
5596 | 5596 |
5597 | 5597 |
5598 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 5598 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
(...skipping 15 matching lines...) Expand all Loading... |
5614 HConstant* instr = | 5614 HConstant* instr = |
5615 new(zone()) HConstant(constant_value, Representation::Tagged()); | 5615 new(zone()) HConstant(constant_value, Representation::Tagged()); |
5616 return ast_context()->ReturnInstruction(instr, expr->id()); | 5616 return ast_context()->ReturnInstruction(instr, expr->id()); |
5617 } | 5617 } |
5618 | 5618 |
5619 LookupResult lookup(isolate()); | 5619 LookupResult lookup(isolate()); |
5620 GlobalPropertyAccess type = | 5620 GlobalPropertyAccess type = |
5621 LookupGlobalProperty(variable, &lookup, false); | 5621 LookupGlobalProperty(variable, &lookup, false); |
5622 | 5622 |
5623 if (type == kUseCell && | 5623 if (type == kUseCell && |
5624 info()->global_object()->IsAccessCheckNeeded()) { | 5624 current_info()->global_object()->IsAccessCheckNeeded()) { |
5625 type = kUseGeneric; | 5625 type = kUseGeneric; |
5626 } | 5626 } |
5627 | 5627 |
5628 if (type == kUseCell) { | 5628 if (type == kUseCell) { |
5629 Handle<GlobalObject> global(info()->global_object()); | 5629 Handle<GlobalObject> global(current_info()->global_object()); |
5630 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 5630 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
5631 HLoadGlobalCell* instr = | 5631 HLoadGlobalCell* instr = |
5632 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); | 5632 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); |
5633 return ast_context()->ReturnInstruction(instr, expr->id()); | 5633 return ast_context()->ReturnInstruction(instr, expr->id()); |
5634 } else { | 5634 } else { |
5635 HValue* context = environment()->LookupContext(); | 5635 HValue* context = environment()->LookupContext(); |
5636 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 5636 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
5637 AddInstruction(global_object); | 5637 AddInstruction(global_object); |
5638 HLoadGlobalGeneric* instr = | 5638 HLoadGlobalGeneric* instr = |
5639 new(zone()) HLoadGlobalGeneric(context, | 5639 new(zone()) HLoadGlobalGeneric(context, |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6210 // Otherwise, find the top prototype. | 6210 // Otherwise, find the top prototype. |
6211 while (proto->GetPrototype(isolate())->IsJSObject()) { | 6211 while (proto->GetPrototype(isolate())->IsJSObject()) { |
6212 proto = proto->GetPrototype(isolate()); | 6212 proto = proto->GetPrototype(isolate()); |
6213 } | 6213 } |
6214 ASSERT(proto->GetPrototype(isolate())->IsNull()); | 6214 ASSERT(proto->GetPrototype(isolate())->IsNull()); |
6215 } | 6215 } |
6216 ASSERT(proto->IsJSObject()); | 6216 ASSERT(proto->IsJSObject()); |
6217 AddInstruction(new(zone()) HCheckPrototypeMaps( | 6217 AddInstruction(new(zone()) HCheckPrototypeMaps( |
6218 Handle<JSObject>(JSObject::cast(map->prototype())), | 6218 Handle<JSObject>(JSObject::cast(map->prototype())), |
6219 Handle<JSObject>(JSObject::cast(proto)), | 6219 Handle<JSObject>(JSObject::cast(proto)), |
6220 zone())); | 6220 zone(), |
| 6221 top_info())); |
6221 } | 6222 } |
6222 | 6223 |
6223 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); | 6224 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); |
6224 Representation representation = ComputeLoadStoreRepresentation(map, lookup); | 6225 Representation representation = ComputeLoadStoreRepresentation(map, lookup); |
6225 bool transition_to_field = lookup->IsTransitionToField(*map); | 6226 bool transition_to_field = lookup->IsTransitionToField(*map); |
6226 | 6227 |
6227 HStoreNamedField *instr; | 6228 HStoreNamedField *instr; |
6228 if (FLAG_track_double_fields && representation.IsDouble()) { | 6229 if (FLAG_track_double_fields && representation.IsDouble()) { |
6229 if (transition_to_field) { | 6230 if (transition_to_field) { |
6230 // The store requires a mutable HeapNumber to be allocated. | 6231 // The store requires a mutable HeapNumber to be allocated. |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6549 // superclass of Assignment and CountOperation, we cannot just pass the | 6550 // superclass of Assignment and CountOperation, we cannot just pass the |
6550 // owning expression instead of position and ast_id separately. | 6551 // owning expression instead of position and ast_id separately. |
6551 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 6552 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
6552 Variable* var, | 6553 Variable* var, |
6553 HValue* value, | 6554 HValue* value, |
6554 int position, | 6555 int position, |
6555 BailoutId ast_id) { | 6556 BailoutId ast_id) { |
6556 LookupResult lookup(isolate()); | 6557 LookupResult lookup(isolate()); |
6557 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 6558 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
6558 if (type == kUseCell) { | 6559 if (type == kUseCell) { |
6559 Handle<GlobalObject> global(info()->global_object()); | 6560 Handle<GlobalObject> global(current_info()->global_object()); |
6560 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 6561 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
6561 HInstruction* instr = | 6562 HInstruction* instr = |
6562 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 6563 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
6563 instr->set_position(position); | 6564 instr->set_position(position); |
6564 AddInstruction(instr); | 6565 AddInstruction(instr); |
6565 if (instr->HasObservableSideEffects()) { | 6566 if (instr->HasObservableSideEffects()) { |
6566 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 6567 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
6567 } | 6568 } |
6568 } else { | 6569 } else { |
6569 HValue* context = environment()->LookupContext(); | 6570 HValue* context = environment()->LookupContext(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6614 if (var->mode() == CONST) { | 6615 if (var->mode() == CONST) { |
6615 return Bailout("unsupported const compound assignment"); | 6616 return Bailout("unsupported const compound assignment"); |
6616 } | 6617 } |
6617 BindIfLive(var, Top()); | 6618 BindIfLive(var, Top()); |
6618 break; | 6619 break; |
6619 | 6620 |
6620 case Variable::CONTEXT: { | 6621 case Variable::CONTEXT: { |
6621 // Bail out if we try to mutate a parameter value in a function | 6622 // Bail out if we try to mutate a parameter value in a function |
6622 // using the arguments object. We do not (yet) correctly handle the | 6623 // using the arguments object. We do not (yet) correctly handle the |
6623 // arguments property of the function. | 6624 // arguments property of the function. |
6624 if (info()->scope()->arguments() != NULL) { | 6625 if (current_info()->scope()->arguments() != NULL) { |
6625 // Parameters will be allocated to context slots. We have no | 6626 // Parameters will be allocated to context slots. We have no |
6626 // direct way to detect that the variable is a parameter so we do | 6627 // direct way to detect that the variable is a parameter so we do |
6627 // a linear search of the parameter variables. | 6628 // a linear search of the parameter variables. |
6628 int count = info()->scope()->num_parameters(); | 6629 int count = current_info()->scope()->num_parameters(); |
6629 for (int i = 0; i < count; ++i) { | 6630 for (int i = 0; i < count; ++i) { |
6630 if (var == info()->scope()->parameter(i)) { | 6631 if (var == current_info()->scope()->parameter(i)) { |
6631 Bailout( | 6632 Bailout( |
6632 "assignment to parameter, function uses arguments object"); | 6633 "assignment to parameter, function uses arguments object"); |
6633 } | 6634 } |
6634 } | 6635 } |
6635 } | 6636 } |
6636 | 6637 |
6637 HStoreContextSlot::Mode mode; | 6638 HStoreContextSlot::Mode mode; |
6638 | 6639 |
6639 switch (var->mode()) { | 6640 switch (var->mode()) { |
6640 case LET: | 6641 case LET: |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6840 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); | 6841 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); |
6841 HValue* value = Pop(); | 6842 HValue* value = Pop(); |
6842 BindIfLive(var, value); | 6843 BindIfLive(var, value); |
6843 return ast_context()->ReturnValue(value); | 6844 return ast_context()->ReturnValue(value); |
6844 } | 6845 } |
6845 | 6846 |
6846 case Variable::CONTEXT: { | 6847 case Variable::CONTEXT: { |
6847 // Bail out if we try to mutate a parameter value in a function using | 6848 // Bail out if we try to mutate a parameter value in a function using |
6848 // the arguments object. We do not (yet) correctly handle the | 6849 // the arguments object. We do not (yet) correctly handle the |
6849 // arguments property of the function. | 6850 // arguments property of the function. |
6850 if (info()->scope()->arguments() != NULL) { | 6851 if (current_info()->scope()->arguments() != NULL) { |
6851 // Parameters will rewrite to context slots. We have no direct way | 6852 // Parameters will rewrite to context slots. We have no direct way |
6852 // to detect that the variable is a parameter. | 6853 // to detect that the variable is a parameter. |
6853 int count = info()->scope()->num_parameters(); | 6854 int count = current_info()->scope()->num_parameters(); |
6854 for (int i = 0; i < count; ++i) { | 6855 for (int i = 0; i < count; ++i) { |
6855 if (var == info()->scope()->parameter(i)) { | 6856 if (var == current_info()->scope()->parameter(i)) { |
6856 return Bailout("assignment to parameter in arguments object"); | 6857 return Bailout("assignment to parameter in arguments object"); |
6857 } | 6858 } |
6858 } | 6859 } |
6859 } | 6860 } |
6860 | 6861 |
6861 CHECK_ALIVE(VisitForValue(expr->value())); | 6862 CHECK_ALIVE(VisitForValue(expr->value())); |
6862 HStoreContextSlot::Mode mode; | 6863 HStoreContextSlot::Mode mode; |
6863 if (expr->op() == Token::ASSIGN) { | 6864 if (expr->op() == Token::ASSIGN) { |
6864 switch (var->mode()) { | 6865 switch (var->mode()) { |
6865 case LET: | 6866 case LET: |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7007 return new(zone()) HConstant(function, Representation::Tagged()); | 7008 return new(zone()) HConstant(function, Representation::Tagged()); |
7008 } | 7009 } |
7009 | 7010 |
7010 // Handle a load from a known field somewhere in the prototype chain. | 7011 // Handle a load from a known field somewhere in the prototype chain. |
7011 LookupInPrototypes(map, name, &lookup); | 7012 LookupInPrototypes(map, name, &lookup); |
7012 if (lookup.IsField()) { | 7013 if (lookup.IsField()) { |
7013 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 7014 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
7014 Handle<JSObject> holder(lookup.holder()); | 7015 Handle<JSObject> holder(lookup.holder()); |
7015 Handle<Map> holder_map(holder->map()); | 7016 Handle<Map> holder_map(holder->map()); |
7016 AddCheckMap(object, map); | 7017 AddCheckMap(object, map); |
7017 AddInstruction( | 7018 AddInstruction(new(zone()) HCheckPrototypeMaps( |
7018 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); | 7019 prototype, holder, zone(), top_info())); |
7019 HValue* holder_value = AddInstruction(new(zone()) | 7020 HValue* holder_value = AddInstruction(new(zone()) |
7020 HConstant(holder, Representation::Tagged())); | 7021 HConstant(holder, Representation::Tagged())); |
7021 return BuildLoadNamedField(holder_value, | 7022 return BuildLoadNamedField(holder_value, |
7022 HObjectAccess::ForField(holder_map, &lookup, name), | 7023 HObjectAccess::ForField(holder_map, &lookup, name), |
7023 ComputeLoadStoreRepresentation(map, &lookup)); | 7024 ComputeLoadStoreRepresentation(map, &lookup)); |
7024 } | 7025 } |
7025 | 7026 |
7026 // Handle a load of a constant function somewhere in the prototype chain. | 7027 // Handle a load of a constant function somewhere in the prototype chain. |
7027 if (lookup.IsConstantFunction()) { | 7028 if (lookup.IsConstantFunction()) { |
7028 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 7029 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
7029 Handle<JSObject> holder(lookup.holder()); | 7030 Handle<JSObject> holder(lookup.holder()); |
7030 Handle<Map> holder_map(holder->map()); | 7031 Handle<Map> holder_map(holder->map()); |
7031 AddCheckMap(object, map); | 7032 AddCheckMap(object, map); |
7032 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); | 7033 AddInstruction(new(zone()) HCheckPrototypeMaps( |
| 7034 prototype, holder, zone(), top_info())); |
7033 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); | 7035 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); |
7034 return new(zone()) HConstant(function, Representation::Tagged()); | 7036 return new(zone()) HConstant(function, Representation::Tagged()); |
7035 } | 7037 } |
7036 | 7038 |
7037 // No luck, do a generic load. | 7039 // No luck, do a generic load. |
7038 return BuildLoadNamedGeneric(object, name, expr); | 7040 return BuildLoadNamedGeneric(object, name, expr); |
7039 } | 7041 } |
7040 | 7042 |
7041 | 7043 |
7042 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 7044 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
(...skipping 16 matching lines...) Expand all Loading... |
7059 if (dependency) { | 7061 if (dependency) { |
7060 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 7062 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
7061 } | 7063 } |
7062 | 7064 |
7063 // Loads from a "stock" fast holey double arrays can elide the hole check. | 7065 // Loads from a "stock" fast holey double arrays can elide the hole check. |
7064 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; | 7066 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; |
7065 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && | 7067 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && |
7066 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | 7068 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
7067 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); | 7069 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); |
7068 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); | 7070 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); |
7069 AddInstruction( | 7071 AddInstruction(new(zone()) HCheckPrototypeMaps( |
7070 new(zone()) HCheckPrototypeMaps(prototype, object_prototype, zone())); | 7072 prototype, object_prototype, zone(), top_info())); |
7071 load_mode = ALLOW_RETURN_HOLE; | 7073 load_mode = ALLOW_RETURN_HOLE; |
7072 graph()->MarkDependsOnEmptyArrayProtoElements(); | 7074 graph()->MarkDependsOnEmptyArrayProtoElements(); |
7073 } | 7075 } |
7074 | 7076 |
7075 return BuildUncheckedMonomorphicElementAccess( | 7077 return BuildUncheckedMonomorphicElementAccess( |
7076 object, key, val, | 7078 object, key, val, |
7077 mapcheck, map->instance_type() == JS_ARRAY_TYPE, | 7079 mapcheck, map->instance_type() == JS_ARRAY_TYPE, |
7078 map->elements_kind(), is_store, load_mode, store_mode); | 7080 map->elements_kind(), is_store, load_mode, store_mode); |
7079 } | 7081 } |
7080 | 7082 |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7575 } | 7577 } |
7576 instr->set_position(expr->position()); | 7578 instr->set_position(expr->position()); |
7577 return ast_context()->ReturnInstruction(instr, expr->id()); | 7579 return ast_context()->ReturnInstruction(instr, expr->id()); |
7578 } | 7580 } |
7579 | 7581 |
7580 | 7582 |
7581 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, | 7583 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, |
7582 Handle<Map> receiver_map) { | 7584 Handle<Map> receiver_map) { |
7583 if (!holder.is_null()) { | 7585 if (!holder.is_null()) { |
7584 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); | 7586 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); |
7585 AddInstruction( | 7587 AddInstruction(new(zone()) HCheckPrototypeMaps( |
7586 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); | 7588 prototype, holder, zone(), top_info())); |
7587 } | 7589 } |
7588 } | 7590 } |
7589 | 7591 |
7590 | 7592 |
7591 void HOptimizedGraphBuilder::AddCheckConstantFunction( | 7593 void HOptimizedGraphBuilder::AddCheckConstantFunction( |
7592 Handle<JSObject> holder, | 7594 Handle<JSObject> holder, |
7593 HValue* receiver, | 7595 HValue* receiver, |
7594 Handle<Map> receiver_map) { | 7596 Handle<Map> receiver_map) { |
7595 // Constant functions have the nice property that the map will change if they | 7597 // Constant functions have the nice property that the map will change if they |
7596 // are overwritten. Therefore it is enough to check the map of the holder and | 7598 // 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... |
7721 if (expr->check_type() == NUMBER_CHECK) { | 7723 if (expr->check_type() == NUMBER_CHECK) { |
7722 if_true->Goto(number_block); | 7724 if_true->Goto(number_block); |
7723 if_true = number_block; | 7725 if_true = number_block; |
7724 number_block->SetJoinId(expr->id()); | 7726 number_block->SetJoinId(expr->id()); |
7725 } | 7727 } |
7726 set_current_block(if_true); | 7728 set_current_block(if_true); |
7727 | 7729 |
7728 expr->ComputeTarget(map, name); | 7730 expr->ComputeTarget(map, name); |
7729 AddCheckPrototypeMaps(expr->holder(), map); | 7731 AddCheckPrototypeMaps(expr->holder(), map); |
7730 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { | 7732 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { |
7731 Handle<JSFunction> caller = info()->closure(); | 7733 Handle<JSFunction> caller = current_info()->closure(); |
7732 SmartArrayPointer<char> caller_name = | 7734 SmartArrayPointer<char> caller_name = |
7733 caller->shared()->DebugName()->ToCString(); | 7735 caller->shared()->DebugName()->ToCString(); |
7734 PrintF("Trying to inline the polymorphic call to %s from %s\n", | 7736 PrintF("Trying to inline the polymorphic call to %s from %s\n", |
7735 *name->ToCString(), | 7737 *name->ToCString(), |
7736 *caller_name); | 7738 *caller_name); |
7737 } | 7739 } |
7738 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { | 7740 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { |
7739 // Trying to inline will signal that we should bailout from the | 7741 // Trying to inline will signal that we should bailout from the |
7740 // entire compilation by setting stack overflow on the visitor. | 7742 // entire compilation by setting stack overflow on the visitor. |
7741 if (HasStackOverflow()) return; | 7743 if (HasStackOverflow()) return; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7805 | 7807 |
7806 | 7808 |
7807 static const int kNotInlinable = 1000000000; | 7809 static const int kNotInlinable = 1000000000; |
7808 | 7810 |
7809 | 7811 |
7810 int HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) { | 7812 int HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) { |
7811 if (!FLAG_use_inlining) return kNotInlinable; | 7813 if (!FLAG_use_inlining) return kNotInlinable; |
7812 | 7814 |
7813 // Precondition: call is monomorphic and we have found a target with the | 7815 // Precondition: call is monomorphic and we have found a target with the |
7814 // appropriate arity. | 7816 // appropriate arity. |
7815 Handle<JSFunction> caller = info()->closure(); | 7817 Handle<JSFunction> caller = current_info()->closure(); |
7816 Handle<SharedFunctionInfo> target_shared(target->shared()); | 7818 Handle<SharedFunctionInfo> target_shared(target->shared()); |
7817 | 7819 |
7818 // Do a quick check on source code length to avoid parsing large | 7820 // Do a quick check on source code length to avoid parsing large |
7819 // inlining candidates. | 7821 // inlining candidates. |
7820 if (target_shared->SourceSize() > | 7822 if (target_shared->SourceSize() > |
7821 Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) { | 7823 Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) { |
7822 TraceInline(target, caller, "target text too big"); | 7824 TraceInline(target, caller, "target text too big"); |
7823 return kNotInlinable; | 7825 return kNotInlinable; |
7824 } | 7826 } |
7825 | 7827 |
(...skipping 15 matching lines...) Expand all Loading... |
7841 bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, | 7843 bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, |
7842 Handle<JSFunction> target, | 7844 Handle<JSFunction> target, |
7843 int arguments_count, | 7845 int arguments_count, |
7844 HValue* implicit_return_value, | 7846 HValue* implicit_return_value, |
7845 BailoutId ast_id, | 7847 BailoutId ast_id, |
7846 BailoutId return_id, | 7848 BailoutId return_id, |
7847 InliningKind inlining_kind) { | 7849 InliningKind inlining_kind) { |
7848 int nodes_added = InliningAstSize(target); | 7850 int nodes_added = InliningAstSize(target); |
7849 if (nodes_added == kNotInlinable) return false; | 7851 if (nodes_added == kNotInlinable) return false; |
7850 | 7852 |
7851 Handle<JSFunction> caller = info()->closure(); | 7853 Handle<JSFunction> caller = current_info()->closure(); |
7852 | 7854 |
7853 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { | 7855 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { |
7854 TraceInline(target, caller, "target AST is too large [early]"); | 7856 TraceInline(target, caller, "target AST is too large [early]"); |
7855 return false; | 7857 return false; |
7856 } | 7858 } |
7857 | 7859 |
7858 #if !defined(V8_TARGET_ARCH_IA32) | 7860 #if !defined(V8_TARGET_ARCH_IA32) |
7859 // Target must be able to use caller's context. | 7861 // Target must be able to use caller's context. |
7860 CompilationInfo* outer_info = info(); | 7862 CompilationInfo* outer_info = current_info(); |
7861 if (target->context() != outer_info->closure()->context() || | 7863 if (target->context() != outer_info->closure()->context() || |
7862 outer_info->scope()->contains_with() || | 7864 outer_info->scope()->contains_with() || |
7863 outer_info->scope()->num_heap_slots() > 0) { | 7865 outer_info->scope()->num_heap_slots() > 0) { |
7864 TraceInline(target, caller, "target requires context change"); | 7866 TraceInline(target, caller, "target requires context change"); |
7865 return false; | 7867 return false; |
7866 } | 7868 } |
7867 #endif | 7869 #endif |
7868 | 7870 |
7869 | 7871 |
7870 // Don't inline deeper than kMaxInliningLevels calls. | 7872 // Don't inline deeper than kMaxInliningLevels calls. |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8285 case kStringCharAt: | 8287 case kStringCharAt: |
8286 if (argument_count == 2 && check_type == STRING_CHECK) { | 8288 if (argument_count == 2 && check_type == STRING_CHECK) { |
8287 HValue* index = Pop(); | 8289 HValue* index = Pop(); |
8288 HValue* string = Pop(); | 8290 HValue* string = Pop(); |
8289 HValue* context = environment()->LookupContext(); | 8291 HValue* context = environment()->LookupContext(); |
8290 ASSERT(!expr->holder().is_null()); | 8292 ASSERT(!expr->holder().is_null()); |
8291 AddInstruction(new(zone()) HCheckPrototypeMaps( | 8293 AddInstruction(new(zone()) HCheckPrototypeMaps( |
8292 Call::GetPrototypeForPrimitiveCheck(STRING_CHECK, | 8294 Call::GetPrototypeForPrimitiveCheck(STRING_CHECK, |
8293 expr->holder()->GetIsolate()), | 8295 expr->holder()->GetIsolate()), |
8294 expr->holder(), | 8296 expr->holder(), |
8295 zone())); | 8297 zone(), |
| 8298 top_info())); |
8296 HInstruction* char_code = | 8299 HInstruction* char_code = |
8297 BuildStringCharCodeAt(context, string, index); | 8300 BuildStringCharCodeAt(context, string, index); |
8298 if (id == kStringCharCodeAt) { | 8301 if (id == kStringCharCodeAt) { |
8299 ast_context()->ReturnInstruction(char_code, expr->id()); | 8302 ast_context()->ReturnInstruction(char_code, expr->id()); |
8300 return true; | 8303 return true; |
8301 } | 8304 } |
8302 AddInstruction(char_code); | 8305 AddInstruction(char_code); |
8303 HInstruction* result = | 8306 HInstruction* result = |
8304 HStringCharFromCode::New(zone(), context, char_code); | 8307 HStringCharFromCode::New(zone(), context, char_code); |
8305 ast_context()->ReturnInstruction(result, expr->id()); | 8308 ast_context()->ReturnInstruction(result, expr->id()); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8436 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) { | 8439 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) { |
8437 return false; | 8440 return false; |
8438 } | 8441 } |
8439 Handle<Map> function_map = expr->GetReceiverTypes()->first(); | 8442 Handle<Map> function_map = expr->GetReceiverTypes()->first(); |
8440 if (function_map->instance_type() != JS_FUNCTION_TYPE || | 8443 if (function_map->instance_type() != JS_FUNCTION_TYPE || |
8441 !expr->target()->shared()->HasBuiltinFunctionId() || | 8444 !expr->target()->shared()->HasBuiltinFunctionId() || |
8442 expr->target()->shared()->builtin_function_id() != kFunctionApply) { | 8445 expr->target()->shared()->builtin_function_id() != kFunctionApply) { |
8443 return false; | 8446 return false; |
8444 } | 8447 } |
8445 | 8448 |
8446 if (info()->scope()->arguments() == NULL) return false; | 8449 if (current_info()->scope()->arguments() == NULL) return false; |
8447 | 8450 |
8448 ZoneList<Expression*>* args = expr->arguments(); | 8451 ZoneList<Expression*>* args = expr->arguments(); |
8449 if (args->length() != 2) return false; | 8452 if (args->length() != 2) return false; |
8450 | 8453 |
8451 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); | 8454 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); |
8452 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; | 8455 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; |
8453 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); | 8456 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); |
8454 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; | 8457 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; |
8455 | 8458 |
8456 // Found pattern f.apply(receiver, arguments). | 8459 // Found pattern f.apply(receiver, arguments). |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8677 | 8680 |
8678 if (global_call) { | 8681 if (global_call) { |
8679 Variable* var = proxy->var(); | 8682 Variable* var = proxy->var(); |
8680 bool known_global_function = false; | 8683 bool known_global_function = false; |
8681 // If there is a global property cell for the name at compile time and | 8684 // If there is a global property cell for the name at compile time and |
8682 // access check is not enabled we assume that the function will not change | 8685 // access check is not enabled we assume that the function will not change |
8683 // and generate optimized code for calling the function. | 8686 // and generate optimized code for calling the function. |
8684 LookupResult lookup(isolate()); | 8687 LookupResult lookup(isolate()); |
8685 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); | 8688 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); |
8686 if (type == kUseCell && | 8689 if (type == kUseCell && |
8687 !info()->global_object()->IsAccessCheckNeeded()) { | 8690 !current_info()->global_object()->IsAccessCheckNeeded()) { |
8688 Handle<GlobalObject> global(info()->global_object()); | 8691 Handle<GlobalObject> global(current_info()->global_object()); |
8689 known_global_function = expr->ComputeGlobalTarget(global, &lookup); | 8692 known_global_function = expr->ComputeGlobalTarget(global, &lookup); |
8690 } | 8693 } |
8691 if (known_global_function) { | 8694 if (known_global_function) { |
8692 // Push the global object instead of the global receiver because | 8695 // Push the global object instead of the global receiver because |
8693 // code generated by the full code generator expects it. | 8696 // code generated by the full code generator expects it. |
8694 HValue* context = environment()->LookupContext(); | 8697 HValue* context = environment()->LookupContext(); |
8695 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 8698 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
8696 PushAndAdd(global_object); | 8699 PushAndAdd(global_object); |
8697 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8700 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
8698 | 8701 |
(...skipping 14 matching lines...) Expand all Loading... |
8713 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. | 8716 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. |
8714 if (FLAG_trace_inlining) { | 8717 if (FLAG_trace_inlining) { |
8715 PrintF("Inlining builtin "); | 8718 PrintF("Inlining builtin "); |
8716 expr->target()->ShortPrint(); | 8719 expr->target()->ShortPrint(); |
8717 PrintF("\n"); | 8720 PrintF("\n"); |
8718 } | 8721 } |
8719 return; | 8722 return; |
8720 } | 8723 } |
8721 if (TryInlineCall(expr)) return; | 8724 if (TryInlineCall(expr)) return; |
8722 | 8725 |
8723 if (expr->target().is_identical_to(info()->closure())) { | 8726 if (expr->target().is_identical_to(current_info()->closure())) { |
8724 graph()->MarkRecursive(); | 8727 graph()->MarkRecursive(); |
8725 } | 8728 } |
8726 | 8729 |
8727 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), | 8730 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), |
8728 argument_count)); | 8731 argument_count)); |
8729 } else { | 8732 } else { |
8730 HValue* context = environment()->LookupContext(); | 8733 HValue* context = environment()->LookupContext(); |
8731 HGlobalObject* receiver = new(zone()) HGlobalObject(context); | 8734 HGlobalObject* receiver = new(zone()) HGlobalObject(context); |
8732 AddInstruction(receiver); | 8735 AddInstruction(receiver); |
8733 PushAndAdd(new(zone()) HPushArgument(receiver)); | 8736 PushAndAdd(new(zone()) HPushArgument(receiver)); |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9223 | 9226 |
9224 case Variable::PARAMETER: | 9227 case Variable::PARAMETER: |
9225 case Variable::LOCAL: | 9228 case Variable::LOCAL: |
9226 BindIfLive(var, after); | 9229 BindIfLive(var, after); |
9227 break; | 9230 break; |
9228 | 9231 |
9229 case Variable::CONTEXT: { | 9232 case Variable::CONTEXT: { |
9230 // Bail out if we try to mutate a parameter value in a function | 9233 // Bail out if we try to mutate a parameter value in a function |
9231 // using the arguments object. We do not (yet) correctly handle the | 9234 // using the arguments object. We do not (yet) correctly handle the |
9232 // arguments property of the function. | 9235 // arguments property of the function. |
9233 if (info()->scope()->arguments() != NULL) { | 9236 if (current_info()->scope()->arguments() != NULL) { |
9234 // Parameters will rewrite to context slots. We have no direct | 9237 // Parameters will rewrite to context slots. We have no direct |
9235 // way to detect that the variable is a parameter so we use a | 9238 // way to detect that the variable is a parameter so we use a |
9236 // linear search of the parameter list. | 9239 // linear search of the parameter list. |
9237 int count = info()->scope()->num_parameters(); | 9240 int count = current_info()->scope()->num_parameters(); |
9238 for (int i = 0; i < count; ++i) { | 9241 for (int i = 0; i < count; ++i) { |
9239 if (var == info()->scope()->parameter(i)) { | 9242 if (var == current_info()->scope()->parameter(i)) { |
9240 return Bailout("assignment to parameter in arguments object"); | 9243 return Bailout("assignment to parameter in arguments object"); |
9241 } | 9244 } |
9242 } | 9245 } |
9243 } | 9246 } |
9244 | 9247 |
9245 HValue* context = BuildContextChainWalk(var); | 9248 HValue* context = BuildContextChainWalk(var); |
9246 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) | 9249 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) |
9247 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; | 9250 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; |
9248 HStoreContextSlot* instr = | 9251 HStoreContextSlot* instr = |
9249 new(zone()) HStoreContextSlot(context, var->index(), mode, after); | 9252 new(zone()) HStoreContextSlot(context, var->index(), mode, after); |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9828 } | 9831 } |
9829 | 9832 |
9830 if (op == Token::INSTANCEOF) { | 9833 if (op == Token::INSTANCEOF) { |
9831 // Check to see if the rhs of the instanceof is a global function not | 9834 // Check to see if the rhs of the instanceof is a global function not |
9832 // residing in new space. If it is we assume that the function will stay the | 9835 // residing in new space. If it is we assume that the function will stay the |
9833 // same. | 9836 // same. |
9834 Handle<JSFunction> target = Handle<JSFunction>::null(); | 9837 Handle<JSFunction> target = Handle<JSFunction>::null(); |
9835 VariableProxy* proxy = expr->right()->AsVariableProxy(); | 9838 VariableProxy* proxy = expr->right()->AsVariableProxy(); |
9836 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); | 9839 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); |
9837 if (global_function && | 9840 if (global_function && |
9838 info()->has_global_object() && | 9841 current_info()->has_global_object() && |
9839 !info()->global_object()->IsAccessCheckNeeded()) { | 9842 !current_info()->global_object()->IsAccessCheckNeeded()) { |
9840 Handle<String> name = proxy->name(); | 9843 Handle<String> name = proxy->name(); |
9841 Handle<GlobalObject> global(info()->global_object()); | 9844 Handle<GlobalObject> global(current_info()->global_object()); |
9842 LookupResult lookup(isolate()); | 9845 LookupResult lookup(isolate()); |
9843 global->Lookup(*name, &lookup); | 9846 global->Lookup(*name, &lookup); |
9844 if (lookup.IsNormal() && lookup.GetValue()->IsJSFunction()) { | 9847 if (lookup.IsNormal() && lookup.GetValue()->IsJSFunction()) { |
9845 Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue())); | 9848 Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue())); |
9846 // If the function is in new space we assume it's more likely to | 9849 // If the function is in new space we assume it's more likely to |
9847 // change and thus prefer the general IC code. | 9850 // change and thus prefer the general IC code. |
9848 if (!isolate()->heap()->InNewSpace(*candidate)) { | 9851 if (!isolate()->heap()->InNewSpace(*candidate)) { |
9849 target = candidate; | 9852 target = candidate; |
9850 } | 9853 } |
9851 } | 9854 } |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10271 | 10274 |
10272 | 10275 |
10273 void HOptimizedGraphBuilder::VisitDeclarations( | 10276 void HOptimizedGraphBuilder::VisitDeclarations( |
10274 ZoneList<Declaration*>* declarations) { | 10277 ZoneList<Declaration*>* declarations) { |
10275 ASSERT(globals_.is_empty()); | 10278 ASSERT(globals_.is_empty()); |
10276 AstVisitor::VisitDeclarations(declarations); | 10279 AstVisitor::VisitDeclarations(declarations); |
10277 if (!globals_.is_empty()) { | 10280 if (!globals_.is_empty()) { |
10278 Handle<FixedArray> array = | 10281 Handle<FixedArray> array = |
10279 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); | 10282 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); |
10280 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); | 10283 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); |
10281 int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | | 10284 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | |
10282 DeclareGlobalsNativeFlag::encode(info()->is_native()) | | 10285 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | |
10283 DeclareGlobalsLanguageMode::encode(info()->language_mode()); | 10286 DeclareGlobalsLanguageMode::encode(current_info()->language_mode()); |
10284 HInstruction* result = new(zone()) HDeclareGlobals( | 10287 HInstruction* result = new(zone()) HDeclareGlobals( |
10285 environment()->LookupContext(), array, flags); | 10288 environment()->LookupContext(), array, flags); |
10286 AddInstruction(result); | 10289 AddInstruction(result); |
10287 globals_.Clear(); | 10290 globals_.Clear(); |
10288 } | 10291 } |
10289 } | 10292 } |
10290 | 10293 |
10291 | 10294 |
10292 void HOptimizedGraphBuilder::VisitVariableDeclaration( | 10295 void HOptimizedGraphBuilder::VisitVariableDeclaration( |
10293 VariableDeclaration* declaration) { | 10296 VariableDeclaration* declaration) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10327 } | 10330 } |
10328 | 10331 |
10329 | 10332 |
10330 void HOptimizedGraphBuilder::VisitFunctionDeclaration( | 10333 void HOptimizedGraphBuilder::VisitFunctionDeclaration( |
10331 FunctionDeclaration* declaration) { | 10334 FunctionDeclaration* declaration) { |
10332 VariableProxy* proxy = declaration->proxy(); | 10335 VariableProxy* proxy = declaration->proxy(); |
10333 Variable* variable = proxy->var(); | 10336 Variable* variable = proxy->var(); |
10334 switch (variable->location()) { | 10337 switch (variable->location()) { |
10335 case Variable::UNALLOCATED: { | 10338 case Variable::UNALLOCATED: { |
10336 globals_.Add(variable->name(), zone()); | 10339 globals_.Add(variable->name(), zone()); |
10337 Handle<SharedFunctionInfo> function = | 10340 Handle<SharedFunctionInfo> function = Compiler::BuildFunctionInfo( |
10338 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); | 10341 declaration->fun(), current_info()->script()); |
10339 // Check for stack-overflow exception. | 10342 // Check for stack-overflow exception. |
10340 if (function.is_null()) return SetStackOverflow(); | 10343 if (function.is_null()) return SetStackOverflow(); |
10341 globals_.Add(function, zone()); | 10344 globals_.Add(function, zone()); |
10342 return; | 10345 return; |
10343 } | 10346 } |
10344 case Variable::PARAMETER: | 10347 case Variable::PARAMETER: |
10345 case Variable::LOCAL: { | 10348 case Variable::LOCAL: { |
10346 CHECK_ALIVE(VisitForValue(declaration->fun())); | 10349 CHECK_ALIVE(VisitForValue(declaration->fun())); |
10347 HValue* value = Pop(); | 10350 HValue* value = Pop(); |
10348 BindIfLive(variable, value); | 10351 BindIfLive(variable, value); |
(...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11609 } | 11612 } |
11610 } | 11613 } |
11611 | 11614 |
11612 #ifdef DEBUG | 11615 #ifdef DEBUG |
11613 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11616 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11614 if (allocator_ != NULL) allocator_->Verify(); | 11617 if (allocator_ != NULL) allocator_->Verify(); |
11615 #endif | 11618 #endif |
11616 } | 11619 } |
11617 | 11620 |
11618 } } // namespace v8::internal | 11621 } } // namespace v8::internal |
OLD | NEW |