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

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 1412223015: [turbofan] Fix receiver binding for inlined callees. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments. Created 5 years, 1 month 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
« no previous file with comments | « no previous file | src/compiler/js-generic-lowering.cc » ('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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/compiler/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/compiler/ast-loop-assignment-analyzer.h" 8 #include "src/compiler/ast-loop-assignment-analyzer.h"
9 #include "src/compiler/control-builders.h" 9 #include "src/compiler/control-builders.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
(...skipping 2294 matching lines...) Expand 10 before | Expand all | Expand 10 after
2305 } 2305 }
2306 2306
2307 2307
2308 void AstGraphBuilder::VisitCall(Call* expr) { 2308 void AstGraphBuilder::VisitCall(Call* expr) {
2309 Expression* callee = expr->expression(); 2309 Expression* callee = expr->expression();
2310 Call::CallType call_type = expr->GetCallType(isolate()); 2310 Call::CallType call_type = expr->GetCallType(isolate());
2311 2311
2312 // Prepare the callee and the receiver to the function call. This depends on 2312 // Prepare the callee and the receiver to the function call. This depends on
2313 // the semantics of the underlying call type. 2313 // the semantics of the underlying call type.
2314 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; 2314 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
2315 Node* receiver_value = NULL; 2315 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
2316 Node* callee_value = NULL; 2316 Node* receiver_value = nullptr;
2317 Node* callee_value = nullptr;
2317 bool possibly_eval = false; 2318 bool possibly_eval = false;
2318 switch (call_type) { 2319 switch (call_type) {
2319 case Call::GLOBAL_CALL: { 2320 case Call::GLOBAL_CALL: {
2320 VariableProxy* proxy = callee->AsVariableProxy(); 2321 VariableProxy* proxy = callee->AsVariableProxy();
2321 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); 2322 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
2322 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); 2323 FrameStateBeforeAndAfter states(this, BeforeId(proxy));
2323 callee_value = 2324 callee_value =
2324 BuildVariableLoad(proxy->var(), expr->expression()->id(), states, 2325 BuildVariableLoad(proxy->var(), expr->expression()->id(), states,
2325 pair, OutputFrameStateCombine::Push()); 2326 pair, OutputFrameStateCombine::Push());
2327 receiver_hint = ConvertReceiverMode::kNullOrUndefined;
2326 receiver_value = jsgraph()->UndefinedConstant(); 2328 receiver_value = jsgraph()->UndefinedConstant();
2327 break; 2329 break;
2328 } 2330 }
2329 case Call::LOOKUP_SLOT_CALL: { 2331 case Call::LOOKUP_SLOT_CALL: {
2330 Variable* variable = callee->AsVariableProxy()->var(); 2332 Variable* variable = callee->AsVariableProxy()->var();
2331 DCHECK(variable->location() == VariableLocation::LOOKUP); 2333 DCHECK(variable->location() == VariableLocation::LOOKUP);
2332 Node* name = jsgraph()->Constant(variable->name()); 2334 Node* name = jsgraph()->Constant(variable->name());
2333 const Operator* op = 2335 const Operator* op =
2334 javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2); 2336 javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2);
2335 Node* pair = NewNode(op, current_context(), name); 2337 Node* pair = NewNode(op, current_context(), name);
(...skipping 19 matching lines...) Expand all
2355 states.AddToNode(callee_value, property->LoadId(), 2357 states.AddToNode(callee_value, property->LoadId(),
2356 OutputFrameStateCombine::Push()); 2358 OutputFrameStateCombine::Push());
2357 } else { 2359 } else {
2358 VisitForValue(property->key()); 2360 VisitForValue(property->key());
2359 FrameStateBeforeAndAfter states(this, property->key()->id()); 2361 FrameStateBeforeAndAfter states(this, property->key()->id());
2360 Node* key = environment()->Pop(); 2362 Node* key = environment()->Pop();
2361 callee_value = BuildKeyedLoad(object, key, pair); 2363 callee_value = BuildKeyedLoad(object, key, pair);
2362 states.AddToNode(callee_value, property->LoadId(), 2364 states.AddToNode(callee_value, property->LoadId(),
2363 OutputFrameStateCombine::Push()); 2365 OutputFrameStateCombine::Push());
2364 } 2366 }
2367 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an
2368 // object for sloppy callees. However the receiver is guaranteed not to
2369 // be null or undefined at this point.
2370 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
2365 receiver_value = environment()->Pop(); 2371 receiver_value = environment()->Pop();
2366 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an
2367 // object for sloppy callees. This could also be modeled explicitly
2368 // here,
2369 // thereby obsoleting the need for a flag to the call operator.
2370 flags = CALL_AS_METHOD; 2372 flags = CALL_AS_METHOD;
2371 2373
2372 } else { 2374 } else {
2375 // TODO(mstarzinger): Cleanup this special handling for super access,
2376 // the stack layout seems to be completely out of sync here, fix this!
2373 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); 2377 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
2374 VisitForValue( 2378 VisitForValue(
2375 property->obj()->AsSuperPropertyReference()->home_object()); 2379 property->obj()->AsSuperPropertyReference()->home_object());
2376 Node* home_object = environment()->Pop(); 2380 Node* home_object = environment()->Pop();
2377 receiver_value = environment()->Pop(); 2381 receiver_value = environment()->Pop();
2378 if (property->key()->IsPropertyName()) { 2382 if (property->key()->IsPropertyName()) {
2379 FrameStateBeforeAndAfter states(this, property->obj()->id()); 2383 FrameStateBeforeAndAfter states(this, property->obj()->id());
2380 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 2384 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2381 callee_value = 2385 callee_value =
2382 BuildNamedSuperLoad(receiver_value, home_object, name, pair); 2386 BuildNamedSuperLoad(receiver_value, home_object, name, pair);
(...skipping 26 matching lines...) Expand all
2409 callee_value = NewNode(common()->Projection(0), pair); 2413 callee_value = NewNode(common()->Projection(0), pair);
2410 receiver_value = NewNode(common()->Projection(1), pair); 2414 receiver_value = NewNode(common()->Projection(1), pair);
2411 PrepareFrameState(pair, expr->LookupId(), 2415 PrepareFrameState(pair, expr->LookupId(),
2412 OutputFrameStateCombine::Push(2)); 2416 OutputFrameStateCombine::Push(2));
2413 break; 2417 break;
2414 } 2418 }
2415 // Fall through. 2419 // Fall through.
2416 case Call::OTHER_CALL: 2420 case Call::OTHER_CALL:
2417 VisitForValue(callee); 2421 VisitForValue(callee);
2418 callee_value = environment()->Pop(); 2422 callee_value = environment()->Pop();
2423 receiver_hint = ConvertReceiverMode::kNullOrUndefined;
2419 receiver_value = jsgraph()->UndefinedConstant(); 2424 receiver_value = jsgraph()->UndefinedConstant();
2420 break; 2425 break;
2421 } 2426 }
2422 2427
2423 // The callee and the receiver both have to be pushed onto the operand stack 2428 // The callee and the receiver both have to be pushed onto the operand stack
2424 // before arguments are being evaluated. 2429 // before arguments are being evaluated.
2425 environment()->Push(callee_value); 2430 environment()->Push(callee_value);
2426 environment()->Push(receiver_value); 2431 environment()->Push(receiver_value);
2427 2432
2428 // Evaluate all arguments to the function call, 2433 // Evaluate all arguments to the function call,
2429 ZoneList<Expression*>* args = expr->arguments(); 2434 ZoneList<Expression*>* args = expr->arguments();
2430 VisitForValues(args); 2435 VisitForValues(args);
2431 2436
2432 // Resolve callee and receiver for a potential direct eval call. This block 2437 // Resolve callee and receiver for a potential direct eval call. This block
2433 // will mutate the callee and receiver values pushed onto the environment. 2438 // will mutate the callee and receiver values pushed onto the environment.
2434 if (possibly_eval && args->length() > 0) { 2439 if (possibly_eval && args->length() > 0) {
2435 int arg_count = args->length(); 2440 int arg_count = args->length();
2436 2441
2437 // Extract callee and source string from the environment. 2442 // Extract callee and source string from the environment.
2438 Node* callee = environment()->Peek(arg_count + 1); 2443 Node* callee = environment()->Peek(arg_count + 1);
2439 Node* source = environment()->Peek(arg_count - 1); 2444 Node* source = environment()->Peek(arg_count - 1);
2440 2445
2441 // Create node to ask for help resolving potential eval call. This will 2446 // Create node to ask for help resolving potential eval call. This will
2442 // provide a fully resolved callee and the corresponding receiver. 2447 // provide a fully resolved callee to patch into the environment.
2443 Node* function = GetFunctionClosure(); 2448 Node* function = GetFunctionClosure();
2444 Node* language = jsgraph()->Constant(language_mode()); 2449 Node* language = jsgraph()->Constant(language_mode());
2445 Node* position = jsgraph()->Constant(current_scope()->start_position()); 2450 Node* position = jsgraph()->Constant(current_scope()->start_position());
2446 const Operator* op = 2451 const Operator* op =
2447 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2452 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2448 Node* new_callee = 2453 Node* new_callee =
2449 NewNode(op, callee, source, function, language, position); 2454 NewNode(op, callee, source, function, language, position);
2450 PrepareFrameState(new_callee, expr->EvalId(), 2455 PrepareFrameState(new_callee, expr->EvalId(),
2451 OutputFrameStateCombine::PokeAt(arg_count + 1)); 2456 OutputFrameStateCombine::PokeAt(arg_count + 1));
2452 2457
2453 // Patch callee on the environment. 2458 // Patch callee on the environment.
2454 environment()->Poke(arg_count + 1, new_callee); 2459 environment()->Poke(arg_count + 1, new_callee);
2455 } 2460 }
2456 2461
2457 // Create node to perform the function call. 2462 // Create node to perform the function call.
2458 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); 2463 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot());
2459 const Operator* call = javascript()->CallFunction(args->length() + 2, flags, 2464 const Operator* call = javascript()->CallFunction(
2460 language_mode(), feedback); 2465 args->length() + 2, flags, language_mode(), feedback, receiver_hint);
2461 Node* value = ProcessArguments(call, args->length() + 2); 2466 Node* value = ProcessArguments(call, args->length() + 2);
2462 environment()->Push(callee_value); 2467 environment()->Push(callee_value);
2463 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); 2468 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push());
2464 environment()->Drop(1); 2469 environment()->Drop(1);
2465 ast_context()->ProduceValue(value); 2470 ast_context()->ProduceValue(value);
2466 } 2471 }
2467 2472
2468 2473
2469 void AstGraphBuilder::VisitCallSuper(Call* expr) { 2474 void AstGraphBuilder::VisitCallSuper(Call* expr) {
2470 SuperCallReference* super = expr->expression()->AsSuperCallReference(); 2475 SuperCallReference* super = expr->expression()->AsSuperCallReference();
(...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after
4222 // Phi does not exist yet, introduce one. 4227 // Phi does not exist yet, introduce one.
4223 value = NewPhi(inputs, value, control); 4228 value = NewPhi(inputs, value, control);
4224 value->ReplaceInput(inputs - 1, other); 4229 value->ReplaceInput(inputs - 1, other);
4225 } 4230 }
4226 return value; 4231 return value;
4227 } 4232 }
4228 4233
4229 } // namespace compiler 4234 } // namespace compiler
4230 } // namespace internal 4235 } // namespace internal
4231 } // namespace v8 4236 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/js-generic-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698