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

Side by Side Diff: src/hydrogen.cc

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

Powered by Google App Engine
This is Rietveld 408576698