OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 9087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9098 return true; | 9098 return true; |
9099 } | 9099 } |
9100 | 9100 |
9101 | 9101 |
9102 bool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr, | 9102 bool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr, |
9103 HValue* function) { | 9103 HValue* function) { |
9104 if (!array_function().is_identical_to(expr->target())) { | 9104 if (!array_function().is_identical_to(expr->target())) { |
9105 return false; | 9105 return false; |
9106 } | 9106 } |
9107 | 9107 |
9108 BuildArrayCall(expr, | 9108 Handle<AllocationSite> site = expr->allocation_site(); |
9109 expr->arguments()->length(), | 9109 if (site.is_null()) return false; |
9110 function, | 9110 |
9111 expr->allocation_site()); | 9111 BuildArrayCall(expr, expr->arguments()->length(), function, site); |
9112 return true; | 9112 return true; |
9113 } | 9113 } |
9114 | 9114 |
9115 | 9115 |
9116 bool HOptimizedGraphBuilder::CanBeFunctionApplyArguments(Call* expr) { | 9116 bool HOptimizedGraphBuilder::CanBeFunctionApplyArguments(Call* expr) { |
9117 ZoneList<Expression*>* args = expr->arguments(); | 9117 ZoneList<Expression*>* args = expr->arguments(); |
9118 if (args->length() != 2) return false; | 9118 if (args->length() != 2) return false; |
9119 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); | 9119 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); |
9120 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; | 9120 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; |
9121 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); | 9121 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9223 } else { | 9223 } else { |
9224 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 9224 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
9225 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { | 9225 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
9226 return Bailout(kPossibleDirectCallToEval); | 9226 return Bailout(kPossibleDirectCallToEval); |
9227 } | 9227 } |
9228 | 9228 |
9229 // The function is on the stack in the unoptimized code during | 9229 // The function is on the stack in the unoptimized code during |
9230 // evaluation of the arguments. | 9230 // evaluation of the arguments. |
9231 CHECK_ALIVE(VisitForValue(expr->expression())); | 9231 CHECK_ALIVE(VisitForValue(expr->expression())); |
9232 HValue* function = Top(); | 9232 HValue* function = Top(); |
9233 if (expr->global_call()) { | 9233 if (function->IsConstant() && |
9234 Variable* var = proxy->var(); | 9234 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
9235 bool known_global_function = false; | 9235 Handle<Object> constant = HConstant::cast(function)->handle(isolate()); |
9236 // If there is a global property cell for the name at compile time and | 9236 Handle<JSFunction> target = Handle<JSFunction>::cast(constant); |
9237 // access check is not enabled we assume that the function will not change | 9237 expr->SetKnownGlobalTarget(target); |
9238 // and generate optimized code for calling the function. | 9238 } |
9239 Handle<GlobalObject> global(current_info()->global_object()); | |
9240 LookupIterator it(global, var->name(), | |
9241 LookupIterator::OWN_SKIP_INTERCEPTOR); | |
9242 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, LOAD); | |
9243 if (type == kUseCell) { | |
9244 known_global_function = expr->ComputeGlobalTarget(global, &it); | |
9245 } | |
9246 if (known_global_function) { | |
9247 Add<HCheckValue>(function, expr->target()); | |
9248 | 9239 |
9249 // Placeholder for the receiver. | 9240 // Placeholder for the receiver. |
9250 Push(graph()->GetConstantUndefined()); | 9241 Push(graph()->GetConstantUndefined()); |
9251 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 9242 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
9252 | 9243 |
9253 // Patch the global object on the stack by the expected receiver. | 9244 if (expr->IsMonomorphic()) { |
9254 HValue* receiver = ImplicitReceiverFor(function, expr->target()); | |
9255 const int receiver_index = argument_count - 1; | |
9256 environment()->SetExpressionStackAt(receiver_index, receiver); | |
9257 | |
9258 if (TryInlineBuiltinFunctionCall(expr)) { | |
9259 if (FLAG_trace_inlining) { | |
9260 PrintF("Inlining builtin "); | |
9261 expr->target()->ShortPrint(); | |
9262 PrintF("\n"); | |
9263 } | |
9264 return; | |
9265 } | |
9266 if (TryInlineApiFunctionCall(expr, receiver)) return; | |
9267 if (TryHandleArrayCall(expr, function)) return; | |
9268 if (TryInlineCall(expr)) return; | |
9269 | |
9270 PushArgumentsFromEnvironment(argument_count); | |
9271 call = BuildCallConstantFunction(expr->target(), argument_count); | |
9272 } else { | |
9273 Push(graph()->GetConstantUndefined()); | |
9274 CHECK_ALIVE(VisitExpressions(expr->arguments())); | |
9275 PushArgumentsFromEnvironment(argument_count); | |
9276 call = New<HCallFunction>(function, argument_count); | |
9277 } | |
9278 | |
9279 } else if (expr->IsMonomorphic()) { | |
9280 Add<HCheckValue>(function, expr->target()); | 9245 Add<HCheckValue>(function, expr->target()); |
9281 | 9246 |
9282 Push(graph()->GetConstantUndefined()); | 9247 // Patch the global object on the stack by the expected receiver. |
9283 CHECK_ALIVE(VisitExpressions(expr->arguments())); | |
9284 | |
9285 HValue* receiver = ImplicitReceiverFor(function, expr->target()); | 9248 HValue* receiver = ImplicitReceiverFor(function, expr->target()); |
9286 const int receiver_index = argument_count - 1; | 9249 const int receiver_index = argument_count - 1; |
9287 environment()->SetExpressionStackAt(receiver_index, receiver); | 9250 environment()->SetExpressionStackAt(receiver_index, receiver); |
9288 | 9251 |
9289 if (TryInlineBuiltinFunctionCall(expr)) { | 9252 if (TryInlineBuiltinFunctionCall(expr)) { |
9290 if (FLAG_trace_inlining) { | 9253 if (FLAG_trace_inlining) { |
9291 PrintF("Inlining builtin "); | 9254 PrintF("Inlining builtin "); |
9292 expr->target()->ShortPrint(); | 9255 expr->target()->ShortPrint(); |
9293 PrintF("\n"); | 9256 PrintF("\n"); |
9294 } | 9257 } |
9295 return; | 9258 return; |
9296 } | 9259 } |
9297 if (TryInlineApiFunctionCall(expr, receiver)) return; | 9260 if (TryInlineApiFunctionCall(expr, receiver)) return; |
9298 | 9261 if (TryHandleArrayCall(expr, function)) return; |
9299 if (TryInlineCall(expr)) return; | 9262 if (TryInlineCall(expr)) return; |
9300 | 9263 |
9301 call = PreProcessCall(New<HInvokeFunction>( | 9264 PushArgumentsFromEnvironment(argument_count); |
9302 function, expr->target(), argument_count)); | 9265 call = BuildCallConstantFunction(expr->target(), argument_count); |
9303 | |
9304 } else { | 9266 } else { |
9305 Push(graph()->GetConstantUndefined()); | |
9306 CHECK_ALIVE(VisitExpressions(expr->arguments())); | |
9307 PushArgumentsFromEnvironment(argument_count); | 9267 PushArgumentsFromEnvironment(argument_count); |
9308 HCallFunction* call_function = | 9268 HCallFunction* call_function = |
9309 New<HCallFunction>(function, argument_count); | 9269 New<HCallFunction>(function, argument_count); |
9310 call = call_function; | 9270 call = call_function; |
9311 if (expr->is_uninitialized() && | 9271 if (expr->is_uninitialized() && |
9312 expr->IsUsingCallFeedbackICSlot(isolate())) { | 9272 expr->IsUsingCallFeedbackICSlot(isolate())) { |
9313 // We've never seen this call before, so let's have Crankshaft learn | 9273 // We've never seen this call before, so let's have Crankshaft learn |
9314 // through the type vector. | 9274 // through the type vector. |
9315 Handle<SharedFunctionInfo> current_shared = | 9275 Handle<SharedFunctionInfo> current_shared = |
9316 function_state()->compilation_info()->shared_info(); | 9276 function_state()->compilation_info()->shared_info(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9435 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); | 9395 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); |
9436 int argument_count = expr->arguments()->length() + 1; // Plus constructor. | 9396 int argument_count = expr->arguments()->length() + 1; // Plus constructor. |
9437 Factory* factory = isolate()->factory(); | 9397 Factory* factory = isolate()->factory(); |
9438 | 9398 |
9439 // The constructor function is on the stack in the unoptimized code | 9399 // The constructor function is on the stack in the unoptimized code |
9440 // during evaluation of the arguments. | 9400 // during evaluation of the arguments. |
9441 CHECK_ALIVE(VisitForValue(expr->expression())); | 9401 CHECK_ALIVE(VisitForValue(expr->expression())); |
9442 HValue* function = Top(); | 9402 HValue* function = Top(); |
9443 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 9403 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
9444 | 9404 |
| 9405 if (function->IsConstant() && |
| 9406 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
| 9407 Handle<Object> constant = HConstant::cast(function)->handle(isolate()); |
| 9408 expr->SetKnownGlobalTarget(Handle<JSFunction>::cast(constant)); |
| 9409 } |
| 9410 |
9445 if (FLAG_inline_construct && | 9411 if (FLAG_inline_construct && |
9446 expr->IsMonomorphic() && | 9412 expr->IsMonomorphic() && |
9447 IsAllocationInlineable(expr->target())) { | 9413 IsAllocationInlineable(expr->target())) { |
9448 Handle<JSFunction> constructor = expr->target(); | 9414 Handle<JSFunction> constructor = expr->target(); |
9449 HValue* check = Add<HCheckValue>(function, constructor); | 9415 HValue* check = Add<HCheckValue>(function, constructor); |
9450 | 9416 |
9451 // Force completion of inobject slack tracking before generating | 9417 // Force completion of inobject slack tracking before generating |
9452 // allocation code to finalize instance size. | 9418 // allocation code to finalize instance size. |
9453 if (constructor->IsInobjectSlackTrackingInProgress()) { | 9419 if (constructor->IsInobjectSlackTrackingInProgress()) { |
9454 constructor->CompleteInobjectSlackTracking(); | 9420 constructor->CompleteInobjectSlackTracking(); |
(...skipping 3967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13422 if (ShouldProduceTraceOutput()) { | 13388 if (ShouldProduceTraceOutput()) { |
13423 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13389 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13424 } | 13390 } |
13425 | 13391 |
13426 #ifdef DEBUG | 13392 #ifdef DEBUG |
13427 graph_->Verify(false); // No full verify. | 13393 graph_->Verify(false); // No full verify. |
13428 #endif | 13394 #endif |
13429 } | 13395 } |
13430 | 13396 |
13431 } } // namespace v8::internal | 13397 } } // namespace v8::internal |
OLD | NEW |