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 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 } | 490 } |
491 | 491 |
492 int visited_count_; | 492 int visited_count_; |
493 ZoneList<HBasicBlock*> stack_; | 493 ZoneList<HBasicBlock*> stack_; |
494 BitVector reachable_; | 494 BitVector reachable_; |
495 HBasicBlock* dont_visit_; | 495 HBasicBlock* dont_visit_; |
496 }; | 496 }; |
497 | 497 |
498 | 498 |
499 void HGraph::Verify(bool do_full_verify) const { | 499 void HGraph::Verify(bool do_full_verify) const { |
| 500 // Allow dereferencing for debug mode verification. |
| 501 AllowHandleDereference allow_handle_deref; |
500 for (int i = 0; i < blocks_.length(); i++) { | 502 for (int i = 0; i < blocks_.length(); i++) { |
501 HBasicBlock* block = blocks_.at(i); | 503 HBasicBlock* block = blocks_.at(i); |
502 | 504 |
503 block->Verify(); | 505 block->Verify(); |
504 | 506 |
505 // Check that every block contains at least one node and that only the last | 507 // Check that every block contains at least one node and that only the last |
506 // node is a control instruction. | 508 // node is a control instruction. |
507 HInstruction* current = block->first(); | 509 HInstruction* current = block->first(); |
508 ASSERT(current != NULL && current->IsBlockEntry()); | 510 ASSERT(current != NULL && current->IsBlockEntry()); |
509 while (current != NULL) { | 511 while (current != NULL) { |
(...skipping 1725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2235 TRACE_GVN_1("Updated first-time accumulated %s\n", | 2237 TRACE_GVN_1("Updated first-time accumulated %s\n", |
2236 *GetGVNFlagsString(*first_time_changes)); | 2238 *GetGVNFlagsString(*first_time_changes)); |
2237 } | 2239 } |
2238 } | 2240 } |
2239 instr = next; | 2241 instr = next; |
2240 } | 2242 } |
2241 } | 2243 } |
2242 | 2244 |
2243 | 2245 |
2244 bool HGlobalValueNumberer::AllowCodeMotion() { | 2246 bool HGlobalValueNumberer::AllowCodeMotion() { |
2245 return info()->shared_info()->opt_count() + 1 < FLAG_max_opt_count; | 2247 return info()->opt_count() + 1 < FLAG_max_opt_count; |
2246 } | 2248 } |
2247 | 2249 |
2248 | 2250 |
2249 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, | 2251 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, |
2250 HBasicBlock* loop_header) { | 2252 HBasicBlock* loop_header) { |
2251 // If we've disabled code motion or we're in a block that unconditionally | 2253 // If we've disabled code motion or we're in a block that unconditionally |
2252 // deoptimizes, don't move any instructions. | 2254 // deoptimizes, don't move any instructions. |
2253 return AllowCodeMotion() && !instr->block()->IsDeoptimizing(); | 2255 return AllowCodeMotion() && !instr->block()->IsDeoptimizing(); |
2254 } | 2256 } |
2255 | 2257 |
(...skipping 4958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7214 unoptimized_code, | 7216 unoptimized_code, |
7215 Handle<Context>(target->context()->native_context()), | 7217 Handle<Context>(target->context()->native_context()), |
7216 isolate(), | 7218 isolate(), |
7217 zone()); | 7219 zone()); |
7218 // The function state is new-allocated because we need to delete it | 7220 // The function state is new-allocated because we need to delete it |
7219 // in two different places. | 7221 // in two different places. |
7220 FunctionState* target_state = new FunctionState( | 7222 FunctionState* target_state = new FunctionState( |
7221 this, &target_info, &target_oracle, inlining_kind); | 7223 this, &target_info, &target_oracle, inlining_kind); |
7222 | 7224 |
7223 HConstant* undefined = graph()->GetConstantUndefined(); | 7225 HConstant* undefined = graph()->GetConstantUndefined(); |
| 7226 bool undefined_receiver = HEnvironment::UseUndefinedReceiver( |
| 7227 target, function, call_kind, inlining_kind); |
7224 HEnvironment* inner_env = | 7228 HEnvironment* inner_env = |
7225 environment()->CopyForInlining(target, | 7229 environment()->CopyForInlining(target, |
7226 arguments_count, | 7230 arguments_count, |
7227 function, | 7231 function, |
7228 undefined, | 7232 undefined, |
7229 call_kind, | 7233 function_state()->inlining_kind(), |
7230 function_state()->inlining_kind()); | 7234 undefined_receiver); |
7231 #ifdef V8_TARGET_ARCH_IA32 | 7235 #ifdef V8_TARGET_ARCH_IA32 |
7232 // IA32 only, overwrite the caller's context in the deoptimization | 7236 // IA32 only, overwrite the caller's context in the deoptimization |
7233 // environment with the correct one. | 7237 // environment with the correct one. |
7234 // | 7238 // |
7235 // TODO(kmillikin): implement the same inlining on other platforms so we | 7239 // TODO(kmillikin): implement the same inlining on other platforms so we |
7236 // can remove the unsightly ifdefs in this function. | 7240 // can remove the unsightly ifdefs in this function. |
7237 HConstant* context = | 7241 HConstant* context = |
7238 new(zone()) HConstant(Handle<Context>(target->context()), | 7242 new(zone()) HConstant(Handle<Context>(target->context()), |
7239 Representation::Tagged()); | 7243 Representation::Tagged()); |
7240 AddInstruction(context); | 7244 AddInstruction(context); |
(...skipping 13 matching lines...) Expand all Loading... |
7254 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone()); | 7258 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone()); |
7255 for (int i = 0; i < arguments_count; i++) { | 7259 for (int i = 0; i < arguments_count; i++) { |
7256 arguments_values->Add(arguments_env->Lookup(i), zone()); | 7260 arguments_values->Add(arguments_env->Lookup(i), zone()); |
7257 } | 7261 } |
7258 } | 7262 } |
7259 | 7263 |
7260 HEnterInlined* enter_inlined = | 7264 HEnterInlined* enter_inlined = |
7261 new(zone()) HEnterInlined(target, | 7265 new(zone()) HEnterInlined(target, |
7262 arguments_count, | 7266 arguments_count, |
7263 function, | 7267 function, |
7264 call_kind, | |
7265 function_state()->inlining_kind(), | 7268 function_state()->inlining_kind(), |
7266 function->scope()->arguments(), | 7269 function->scope()->arguments(), |
7267 arguments_values); | 7270 arguments_values, |
| 7271 undefined_receiver); |
7268 function_state()->set_entry(enter_inlined); | 7272 function_state()->set_entry(enter_inlined); |
7269 AddInstruction(enter_inlined); | 7273 AddInstruction(enter_inlined); |
7270 | 7274 |
7271 // If the function uses arguments object create and bind one. | 7275 // If the function uses arguments object create and bind one. |
7272 if (function->scope()->arguments() != NULL) { | 7276 if (function->scope()->arguments() != NULL) { |
7273 ASSERT(function->scope()->arguments()->IsStackAllocated()); | 7277 ASSERT(function->scope()->arguments()->IsStackAllocated()); |
7274 inner_env->Bind(function->scope()->arguments(), | 7278 inner_env->Bind(function->scope()->arguments(), |
7275 graph()->GetArgumentsObject()); | 7279 graph()->GetArgumentsObject()); |
7276 } | 7280 } |
7277 | 7281 |
(...skipping 2599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9877 new_env->ClearHistory(); | 9881 new_env->ClearHistory(); |
9878 return new_env; | 9882 return new_env; |
9879 } | 9883 } |
9880 | 9884 |
9881 | 9885 |
9882 HEnvironment* HEnvironment::CopyForInlining( | 9886 HEnvironment* HEnvironment::CopyForInlining( |
9883 Handle<JSFunction> target, | 9887 Handle<JSFunction> target, |
9884 int arguments, | 9888 int arguments, |
9885 FunctionLiteral* function, | 9889 FunctionLiteral* function, |
9886 HConstant* undefined, | 9890 HConstant* undefined, |
9887 CallKind call_kind, | 9891 InliningKind inlining_kind, |
9888 InliningKind inlining_kind) const { | 9892 bool undefined_receiver) const { |
9889 ASSERT(frame_type() == JS_FUNCTION); | 9893 ASSERT(frame_type() == JS_FUNCTION); |
9890 | 9894 |
9891 // Outer environment is a copy of this one without the arguments. | 9895 // Outer environment is a copy of this one without the arguments. |
9892 int arity = function->scope()->num_parameters(); | 9896 int arity = function->scope()->num_parameters(); |
9893 | 9897 |
9894 HEnvironment* outer = Copy(); | 9898 HEnvironment* outer = Copy(); |
9895 outer->Drop(arguments + 1); // Including receiver. | 9899 outer->Drop(arguments + 1); // Including receiver. |
9896 outer->ClearHistory(); | 9900 outer->ClearHistory(); |
9897 | 9901 |
9898 if (inlining_kind == CONSTRUCT_CALL_RETURN) { | 9902 if (inlining_kind == CONSTRUCT_CALL_RETURN) { |
(...skipping 20 matching lines...) Expand all Loading... |
9919 new(zone()) HEnvironment(outer, function->scope(), target, zone()); | 9923 new(zone()) HEnvironment(outer, function->scope(), target, zone()); |
9920 // Get the argument values from the original environment. | 9924 // Get the argument values from the original environment. |
9921 for (int i = 0; i <= arity; ++i) { // Include receiver. | 9925 for (int i = 0; i <= arity; ++i) { // Include receiver. |
9922 HValue* push = (i <= arguments) ? | 9926 HValue* push = (i <= arguments) ? |
9923 ExpressionStackAt(arguments - i) : undefined; | 9927 ExpressionStackAt(arguments - i) : undefined; |
9924 inner->SetValueAt(i, push); | 9928 inner->SetValueAt(i, push); |
9925 } | 9929 } |
9926 // If the function we are inlining is a strict mode function or a | 9930 // If the function we are inlining is a strict mode function or a |
9927 // builtin function, pass undefined as the receiver for function | 9931 // builtin function, pass undefined as the receiver for function |
9928 // calls (instead of the global receiver). | 9932 // calls (instead of the global receiver). |
9929 if ((target->shared()->native() || !function->is_classic_mode()) && | 9933 if (undefined_receiver) { |
9930 call_kind == CALL_AS_FUNCTION && inlining_kind != CONSTRUCT_CALL_RETURN) { | |
9931 inner->SetValueAt(0, undefined); | 9934 inner->SetValueAt(0, undefined); |
9932 } | 9935 } |
9933 inner->SetValueAt(arity + 1, LookupContext()); | 9936 inner->SetValueAt(arity + 1, LookupContext()); |
9934 for (int i = arity + 2; i < inner->length(); ++i) { | 9937 for (int i = arity + 2; i < inner->length(); ++i) { |
9935 inner->SetValueAt(i, undefined); | 9938 inner->SetValueAt(i, undefined); |
9936 } | 9939 } |
9937 | 9940 |
9938 inner->set_ast_id(BailoutId::FunctionEntry()); | 9941 inner->set_ast_id(BailoutId::FunctionEntry()); |
9939 return inner; | 9942 return inner; |
9940 } | 9943 } |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10301 } | 10304 } |
10302 } | 10305 } |
10303 | 10306 |
10304 #ifdef DEBUG | 10307 #ifdef DEBUG |
10305 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10308 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
10306 if (allocator_ != NULL) allocator_->Verify(); | 10309 if (allocator_ != NULL) allocator_->Verify(); |
10307 #endif | 10310 #endif |
10308 } | 10311 } |
10309 | 10312 |
10310 } } // namespace v8::internal | 10313 } } // namespace v8::internal |
OLD | NEW |