| 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 |