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

Side by Side Diff: src/hydrogen.cc

Issue 16782004: Reland "Enable map dependency to in-flight compilation info." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: The fix. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698