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

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

Issue 2514393002: [fullcodegen] Remove deprecated support for lookup variables, eval and with. (Closed)
Patch Set: Address comment Created 4 years 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 | « src/compiler/ast-graph-builder.h ('k') | src/full-codegen/arm/full-codegen-arm.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/ast/compile-time-value.h" 7 #include "src/ast/compile-time-value.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/compilation-info.h" 9 #include "src/compilation-info.h"
10 #include "src/compiler.h" 10 #include "src/compiler.h"
(...skipping 1095 matching lines...) Expand 10 before | Expand all | Expand 10 after
1106 environment()->Bind(variable, value); 1106 environment()->Bind(variable, value);
1107 } 1107 }
1108 break; 1108 break;
1109 case VariableLocation::CONTEXT: 1109 case VariableLocation::CONTEXT:
1110 if (variable->binding_needs_init()) { 1110 if (variable->binding_needs_init()) {
1111 Node* value = jsgraph()->TheHoleConstant(); 1111 Node* value = jsgraph()->TheHoleConstant();
1112 const Operator* op = javascript()->StoreContext(0, variable->index()); 1112 const Operator* op = javascript()->StoreContext(0, variable->index());
1113 NewNode(op, current_context(), value); 1113 NewNode(op, current_context(), value);
1114 } 1114 }
1115 break; 1115 break;
1116 case VariableLocation::LOOKUP: { 1116 case VariableLocation::LOOKUP:
1117 DCHECK(!variable->binding_needs_init());
1118 Node* name = jsgraph()->Constant(variable->name());
1119 const Operator* op = javascript()->CallRuntime(Runtime::kDeclareEvalVar);
1120 Node* store = NewNode(op, name);
1121 PrepareFrameState(store, decl->proxy()->id());
1122 break;
1123 }
1124 case VariableLocation::MODULE: 1117 case VariableLocation::MODULE:
1125 UNREACHABLE(); 1118 UNREACHABLE();
1126 } 1119 }
1127 } 1120 }
1128 1121
1129 1122
1130 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) { 1123 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
1131 Variable* variable = decl->proxy()->var(); 1124 Variable* variable = decl->proxy()->var();
1132 switch (variable->location()) { 1125 switch (variable->location()) {
1133 case VariableLocation::UNALLOCATED: { 1126 case VariableLocation::UNALLOCATED: {
(...skipping 15 matching lines...) Expand all
1149 environment()->Bind(variable, value); 1142 environment()->Bind(variable, value);
1150 break; 1143 break;
1151 } 1144 }
1152 case VariableLocation::CONTEXT: { 1145 case VariableLocation::CONTEXT: {
1153 VisitForValue(decl->fun()); 1146 VisitForValue(decl->fun());
1154 Node* value = environment()->Pop(); 1147 Node* value = environment()->Pop();
1155 const Operator* op = javascript()->StoreContext(0, variable->index()); 1148 const Operator* op = javascript()->StoreContext(0, variable->index());
1156 NewNode(op, current_context(), value); 1149 NewNode(op, current_context(), value);
1157 break; 1150 break;
1158 } 1151 }
1159 case VariableLocation::LOOKUP: { 1152 case VariableLocation::LOOKUP:
1160 VisitForValue(decl->fun());
1161 Node* value = environment()->Pop();
1162 Node* name = jsgraph()->Constant(variable->name());
1163 const Operator* op =
1164 javascript()->CallRuntime(Runtime::kDeclareEvalFunction);
1165 Node* store = NewNode(op, name, value);
1166 PrepareFrameState(store, decl->proxy()->id());
1167 break;
1168 }
1169 case VariableLocation::MODULE: 1153 case VariableLocation::MODULE:
1170 UNREACHABLE(); 1154 UNREACHABLE();
1171 } 1155 }
1172 } 1156 }
1173 1157
1174 1158
1175 void AstGraphBuilder::VisitBlock(Block* stmt) { 1159 void AstGraphBuilder::VisitBlock(Block* stmt) {
1176 BlockBuilder block(this); 1160 BlockBuilder block(this);
1177 ControlScopeForBreakable scope(this, stmt, &block); 1161 ControlScopeForBreakable scope(this, stmt, &block);
1178 if (stmt->labels() != nullptr) block.BeginBlock(); 1162 if (stmt->labels() != nullptr) block.BeginBlock();
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after
2266 break; 2250 break;
2267 } 2251 }
2268 } 2252 }
2269 ast_context()->ProduceValue(expr, value); 2253 ast_context()->ProduceValue(expr, value);
2270 } 2254 }
2271 2255
2272 2256
2273 void AstGraphBuilder::VisitCall(Call* expr) { 2257 void AstGraphBuilder::VisitCall(Call* expr) {
2274 Expression* callee = expr->expression(); 2258 Expression* callee = expr->expression();
2275 Call::CallType call_type = expr->GetCallType(); 2259 Call::CallType call_type = expr->GetCallType();
2260 CHECK(!expr->is_possibly_eval());
2276 2261
2277 // Prepare the callee and the receiver to the function call. This depends on 2262 // Prepare the callee and the receiver to the function call. This depends on
2278 // the semantics of the underlying call type. 2263 // the semantics of the underlying call type.
2279 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; 2264 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
2280 Node* receiver_value = nullptr; 2265 Node* receiver_value = nullptr;
2281 Node* callee_value = nullptr; 2266 Node* callee_value = nullptr;
2282 if (expr->is_possibly_eval()) { 2267 switch (call_type) {
2283 if (callee->AsVariableProxy()->var()->IsLookupSlot()) { 2268 case Call::GLOBAL_CALL: {
2284 Variable* variable = callee->AsVariableProxy()->var(); 2269 VariableProxy* proxy = callee->AsVariableProxy();
2285 Node* name = jsgraph()->Constant(variable->name()); 2270 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
2286 const Operator* op = 2271 PrepareEagerCheckpoint(BeforeId(proxy));
2287 javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall); 2272 callee_value = BuildVariableLoad(proxy->var(), expr->expression()->id(),
2288 Node* pair = NewNode(op, name); 2273 pair, OutputFrameStateCombine::Push());
2289 callee_value = NewNode(common()->Projection(0), pair); 2274 receiver_hint = ConvertReceiverMode::kNullOrUndefined;
2290 receiver_value = NewNode(common()->Projection(1), pair); 2275 receiver_value = jsgraph()->UndefinedConstant();
2291 PrepareFrameState(pair, expr->LookupId(), 2276 break;
2292 OutputFrameStateCombine::Push(2)); 2277 }
2293 } else { 2278 case Call::NAMED_PROPERTY_CALL: {
2279 Property* property = callee->AsProperty();
2280 VectorSlotPair feedback =
2281 CreateVectorSlotPair(property->PropertyFeedbackSlot());
2282 VisitForValue(property->obj());
2283 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2284 Node* object = environment()->Top();
2285 callee_value = BuildNamedLoad(object, name, feedback);
2286 PrepareFrameState(callee_value, property->LoadId(),
2287 OutputFrameStateCombine::Push());
2288 // Note that a property call requires the receiver to be wrapped into
2289 // an object for sloppy callees. However the receiver is guaranteed
2290 // not to be null or undefined at this point.
2291 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
2292 receiver_value = environment()->Pop();
2293 break;
2294 }
2295 case Call::KEYED_PROPERTY_CALL: {
2296 Property* property = callee->AsProperty();
2297 VectorSlotPair feedback =
2298 CreateVectorSlotPair(property->PropertyFeedbackSlot());
2299 VisitForValue(property->obj());
2300 VisitForValue(property->key());
2301 Node* key = environment()->Pop();
2302 Node* object = environment()->Top();
2303 callee_value = BuildKeyedLoad(object, key, feedback);
2304 PrepareFrameState(callee_value, property->LoadId(),
2305 OutputFrameStateCombine::Push());
2306 // Note that a property call requires the receiver to be wrapped into
2307 // an object for sloppy callees. However the receiver is guaranteed
2308 // not to be null or undefined at this point.
2309 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
2310 receiver_value = environment()->Pop();
2311 break;
2312 }
2313 case Call::NAMED_SUPER_PROPERTY_CALL: {
2314 Property* property = callee->AsProperty();
2315 SuperPropertyReference* super_ref =
2316 property->obj()->AsSuperPropertyReference();
2317 VisitForValue(super_ref->home_object());
2318 VisitForValue(super_ref->this_var());
2319 Node* home = environment()->Peek(1);
2320 Node* object = environment()->Top();
2321 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2322 callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair());
2323 PrepareFrameState(callee_value, property->LoadId(),
2324 OutputFrameStateCombine::Push());
2325 // Note that a property call requires the receiver to be wrapped into
2326 // an object for sloppy callees. Since the receiver is not the target of
2327 // the load, it could very well be null or undefined at this point.
2328 receiver_value = environment()->Pop();
2329 environment()->Drop(1);
2330 break;
2331 }
2332 case Call::KEYED_SUPER_PROPERTY_CALL: {
2333 Property* property = callee->AsProperty();
2334 SuperPropertyReference* super_ref =
2335 property->obj()->AsSuperPropertyReference();
2336 VisitForValue(super_ref->home_object());
2337 VisitForValue(super_ref->this_var());
2338 environment()->Push(environment()->Top()); // Duplicate this_var.
2339 environment()->Push(environment()->Peek(2)); // Duplicate home_obj.
2340 VisitForValue(property->key());
2341 Node* key = environment()->Pop();
2342 Node* home = environment()->Pop();
2343 Node* object = environment()->Pop();
2344 callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair());
2345 PrepareFrameState(callee_value, property->LoadId(),
2346 OutputFrameStateCombine::Push());
2347 // Note that a property call requires the receiver to be wrapped into
2348 // an object for sloppy callees. Since the receiver is not the target of
2349 // the load, it could very well be null or undefined at this point.
2350 receiver_value = environment()->Pop();
2351 environment()->Drop(1);
2352 break;
2353 }
2354 case Call::SUPER_CALL:
2355 return VisitCallSuper(expr);
2356 case Call::OTHER_CALL:
2294 VisitForValue(callee); 2357 VisitForValue(callee);
2295 callee_value = environment()->Pop(); 2358 callee_value = environment()->Pop();
2296 receiver_hint = ConvertReceiverMode::kNullOrUndefined; 2359 receiver_hint = ConvertReceiverMode::kNullOrUndefined;
2297 receiver_value = jsgraph()->UndefinedConstant(); 2360 receiver_value = jsgraph()->UndefinedConstant();
2298 } 2361 break;
2299 } else { 2362 case Call::WITH_CALL:
2300 switch (call_type) { 2363 UNREACHABLE();
2301 case Call::GLOBAL_CALL: {
2302 VariableProxy* proxy = callee->AsVariableProxy();
2303 VectorSlotPair pair =
2304 CreateVectorSlotPair(proxy->VariableFeedbackSlot());
2305 PrepareEagerCheckpoint(BeforeId(proxy));
2306 callee_value = BuildVariableLoad(proxy->var(), expr->expression()->id(),
2307 pair, OutputFrameStateCombine::Push());
2308 receiver_hint = ConvertReceiverMode::kNullOrUndefined;
2309 receiver_value = jsgraph()->UndefinedConstant();
2310 break;
2311 }
2312 case Call::WITH_CALL: {
2313 Variable* variable = callee->AsVariableProxy()->var();
2314 Node* name = jsgraph()->Constant(variable->name());
2315 const Operator* op =
2316 javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall);
2317 Node* pair = NewNode(op, name);
2318 callee_value = NewNode(common()->Projection(0), pair);
2319 receiver_value = NewNode(common()->Projection(1), pair);
2320 PrepareFrameState(pair, expr->LookupId(),
2321 OutputFrameStateCombine::Push(2));
2322 break;
2323 }
2324 case Call::NAMED_PROPERTY_CALL: {
2325 Property* property = callee->AsProperty();
2326 VectorSlotPair feedback =
2327 CreateVectorSlotPair(property->PropertyFeedbackSlot());
2328 VisitForValue(property->obj());
2329 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2330 Node* object = environment()->Top();
2331 callee_value = BuildNamedLoad(object, name, feedback);
2332 PrepareFrameState(callee_value, property->LoadId(),
2333 OutputFrameStateCombine::Push());
2334 // Note that a property call requires the receiver to be wrapped into
2335 // an object for sloppy callees. However the receiver is guaranteed
2336 // not to be null or undefined at this point.
2337 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
2338 receiver_value = environment()->Pop();
2339 break;
2340 }
2341 case Call::KEYED_PROPERTY_CALL: {
2342 Property* property = callee->AsProperty();
2343 VectorSlotPair feedback =
2344 CreateVectorSlotPair(property->PropertyFeedbackSlot());
2345 VisitForValue(property->obj());
2346 VisitForValue(property->key());
2347 Node* key = environment()->Pop();
2348 Node* object = environment()->Top();
2349 callee_value = BuildKeyedLoad(object, key, feedback);
2350 PrepareFrameState(callee_value, property->LoadId(),
2351 OutputFrameStateCombine::Push());
2352 // Note that a property call requires the receiver to be wrapped into
2353 // an object for sloppy callees. However the receiver is guaranteed
2354 // not to be null or undefined at this point.
2355 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
2356 receiver_value = environment()->Pop();
2357 break;
2358 }
2359 case Call::NAMED_SUPER_PROPERTY_CALL: {
2360 Property* property = callee->AsProperty();
2361 SuperPropertyReference* super_ref =
2362 property->obj()->AsSuperPropertyReference();
2363 VisitForValue(super_ref->home_object());
2364 VisitForValue(super_ref->this_var());
2365 Node* home = environment()->Peek(1);
2366 Node* object = environment()->Top();
2367 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2368 callee_value =
2369 BuildNamedSuperLoad(object, home, name, VectorSlotPair());
2370 PrepareFrameState(callee_value, property->LoadId(),
2371 OutputFrameStateCombine::Push());
2372 // Note that a property call requires the receiver to be wrapped into
2373 // an object for sloppy callees. Since the receiver is not the target of
2374 // the load, it could very well be null or undefined at this point.
2375 receiver_value = environment()->Pop();
2376 environment()->Drop(1);
2377 break;
2378 }
2379 case Call::KEYED_SUPER_PROPERTY_CALL: {
2380 Property* property = callee->AsProperty();
2381 SuperPropertyReference* super_ref =
2382 property->obj()->AsSuperPropertyReference();
2383 VisitForValue(super_ref->home_object());
2384 VisitForValue(super_ref->this_var());
2385 environment()->Push(environment()->Top()); // Duplicate this_var.
2386 environment()->Push(environment()->Peek(2)); // Duplicate home_obj.
2387 VisitForValue(property->key());
2388 Node* key = environment()->Pop();
2389 Node* home = environment()->Pop();
2390 Node* object = environment()->Pop();
2391 callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair());
2392 PrepareFrameState(callee_value, property->LoadId(),
2393 OutputFrameStateCombine::Push());
2394 // Note that a property call requires the receiver to be wrapped into
2395 // an object for sloppy callees. Since the receiver is not the target of
2396 // the load, it could very well be null or undefined at this point.
2397 receiver_value = environment()->Pop();
2398 environment()->Drop(1);
2399 break;
2400 }
2401 case Call::SUPER_CALL:
2402 return VisitCallSuper(expr);
2403 case Call::OTHER_CALL:
2404 VisitForValue(callee);
2405 callee_value = environment()->Pop();
2406 receiver_hint = ConvertReceiverMode::kNullOrUndefined;
2407 receiver_value = jsgraph()->UndefinedConstant();
2408 break;
2409 }
2410 } 2364 }
2411 2365
2412 // The callee and the receiver both have to be pushed onto the operand stack 2366 // The callee and the receiver both have to be pushed onto the operand stack
2413 // before arguments are being evaluated. 2367 // before arguments are being evaluated.
2414 environment()->Push(callee_value); 2368 environment()->Push(callee_value);
2415 environment()->Push(receiver_value); 2369 environment()->Push(receiver_value);
2416 2370
2417 // Evaluate all arguments to the function call, 2371 // Evaluate all arguments to the function call,
2418 ZoneList<Expression*>* args = expr->arguments(); 2372 ZoneList<Expression*>* args = expr->arguments();
2419 VisitForValues(args); 2373 VisitForValues(args);
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
3068 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair( 3022 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
3069 FeedbackVectorSlot slot) const { 3023 FeedbackVectorSlot slot) const {
3070 return VectorSlotPair(handle(info()->closure()->feedback_vector()), slot); 3024 return VectorSlotPair(handle(info()->closure()->feedback_vector()), slot);
3071 } 3025 }
3072 3026
3073 3027
3074 void AstGraphBuilder::VisitRewritableExpression(RewritableExpression* node) { 3028 void AstGraphBuilder::VisitRewritableExpression(RewritableExpression* node) {
3075 Visit(node->expression()); 3029 Visit(node->expression());
3076 } 3030 }
3077 3031
3078
3079 namespace {
3080
3081 // Limit of context chain length to which inline check is possible.
3082 const int kMaxCheckDepth = 30;
3083
3084 // Sentinel for {TryLoadDynamicVariable} disabling inline checks.
3085 const uint32_t kFullCheckRequired = -1;
3086
3087 } // namespace
3088
3089
3090 uint32_t AstGraphBuilder::ComputeBitsetForDynamicGlobal(Variable* variable) {
3091 DCHECK_EQ(DYNAMIC_GLOBAL, variable->mode());
3092 uint32_t check_depths = 0;
3093 for (Scope* s = current_scope(); s != nullptr; s = s->outer_scope()) {
3094 if (!s->NeedsContext()) continue;
3095 if (!s->calls_sloppy_eval()) continue;
3096 int depth = current_scope()->ContextChainLength(s);
3097 if (depth > kMaxCheckDepth) return kFullCheckRequired;
3098 check_depths |= 1 << depth;
3099 }
3100 return check_depths;
3101 }
3102
3103
3104 uint32_t AstGraphBuilder::ComputeBitsetForDynamicContext(Variable* variable) {
3105 DCHECK_EQ(DYNAMIC_LOCAL, variable->mode());
3106 uint32_t check_depths = 0;
3107 for (Scope* s = current_scope(); s != nullptr; s = s->outer_scope()) {
3108 if (!s->NeedsContext()) continue;
3109 if (!s->calls_sloppy_eval() && s != variable->scope()) continue;
3110 int depth = current_scope()->ContextChainLength(s);
3111 if (depth > kMaxCheckDepth) return kFullCheckRequired;
3112 check_depths |= 1 << depth;
3113 if (s == variable->scope()) break;
3114 }
3115 return check_depths;
3116 }
3117
3118 float AstGraphBuilder::ComputeCallFrequency(FeedbackVectorSlot slot) const { 3032 float AstGraphBuilder::ComputeCallFrequency(FeedbackVectorSlot slot) const {
3119 if (slot.IsInvalid()) return 0.0f; 3033 if (slot.IsInvalid()) return 0.0f;
3120 Handle<TypeFeedbackVector> feedback_vector( 3034 Handle<TypeFeedbackVector> feedback_vector(
3121 info()->closure()->feedback_vector(), isolate()); 3035 info()->closure()->feedback_vector(), isolate());
3122 CallICNexus nexus(feedback_vector, slot); 3036 CallICNexus nexus(feedback_vector, slot);
3123 return nexus.ComputeCallFrequency() * invocation_frequency_; 3037 return nexus.ComputeCallFrequency() * invocation_frequency_;
3124 } 3038 }
3125 3039
3126 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) { 3040 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
3127 DCHECK(environment()->stack_height() >= arity); 3041 DCHECK(environment()->stack_height() >= arity);
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
3367 Node* value = NewNode(op, current_context()); 3281 Node* value = NewNode(op, current_context());
3368 // TODO(titzer): initialization checks are redundant for already 3282 // TODO(titzer): initialization checks are redundant for already
3369 // initialized immutable context loads, but only specialization knows. 3283 // initialized immutable context loads, but only specialization knows.
3370 // Maybe specializer should be a parameter to the graph builder? 3284 // Maybe specializer should be a parameter to the graph builder?
3371 if (variable->binding_needs_init()) { 3285 if (variable->binding_needs_init()) {
3372 // Perform check for uninitialized let/const variables. 3286 // Perform check for uninitialized let/const variables.
3373 value = BuildHoleCheckThenThrow(value, variable, value, bailout_id); 3287 value = BuildHoleCheckThenThrow(value, variable, value, bailout_id);
3374 } 3288 }
3375 return value; 3289 return value;
3376 } 3290 }
3377 case VariableLocation::LOOKUP: { 3291 case VariableLocation::LOOKUP:
3378 // Dynamic lookup of context variable (anywhere in the chain).
3379 Handle<String> name = variable->name();
3380 if (Node* node = TryLoadDynamicVariable(variable, name, bailout_id,
3381 feedback, combine, typeof_mode)) {
3382 return node;
3383 }
3384 Node* value = BuildDynamicLoad(name, typeof_mode);
3385 PrepareFrameState(value, bailout_id, combine);
3386 return value;
3387 }
3388 case VariableLocation::MODULE: 3292 case VariableLocation::MODULE:
3389 UNREACHABLE(); 3293 UNREACHABLE();
3390 } 3294 }
3391 UNREACHABLE(); 3295 UNREACHABLE();
3392 return nullptr; 3296 return nullptr;
3393 } 3297 }
3394 3298
3395 3299
3396 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable, 3300 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable,
3397 BailoutId bailout_id, 3301 BailoutId bailout_id,
3398 OutputFrameStateCombine combine) { 3302 OutputFrameStateCombine combine) {
3399 switch (variable->location()) { 3303 switch (variable->location()) {
3400 case VariableLocation::UNALLOCATED: { 3304 case VariableLocation::UNALLOCATED: {
3401 // Global var, const, or let variable. 3305 // Global var, const, or let variable.
3402 Node* global = BuildLoadGlobalObject(); 3306 Node* global = BuildLoadGlobalObject();
3403 Node* name = jsgraph()->Constant(variable->name()); 3307 Node* name = jsgraph()->Constant(variable->name());
3404 const Operator* op = javascript()->DeleteProperty(language_mode()); 3308 const Operator* op = javascript()->DeleteProperty(language_mode());
3405 Node* result = NewNode(op, global, name); 3309 Node* result = NewNode(op, global, name);
3406 PrepareFrameState(result, bailout_id, combine); 3310 PrepareFrameState(result, bailout_id, combine);
3407 return result; 3311 return result;
3408 } 3312 }
3409 case VariableLocation::PARAMETER: 3313 case VariableLocation::PARAMETER:
3410 case VariableLocation::LOCAL: 3314 case VariableLocation::LOCAL:
3411 case VariableLocation::CONTEXT: { 3315 case VariableLocation::CONTEXT: {
3412 // Local var, const, or let variable or context variable. 3316 // Local var, const, or let variable or context variable.
3413 return jsgraph()->BooleanConstant(variable->is_this()); 3317 return jsgraph()->BooleanConstant(variable->is_this());
3414 } 3318 }
3415 case VariableLocation::LOOKUP: { 3319 case VariableLocation::LOOKUP:
3416 // Dynamic lookup of context variable (anywhere in the chain).
3417 Node* name = jsgraph()->Constant(variable->name());
3418 const Operator* op =
3419 javascript()->CallRuntime(Runtime::kDeleteLookupSlot);
3420 Node* result = NewNode(op, name);
3421 PrepareFrameState(result, bailout_id, combine);
3422 return result;
3423 }
3424 case VariableLocation::MODULE: 3320 case VariableLocation::MODULE:
3425 UNREACHABLE(); 3321 UNREACHABLE();
3426 } 3322 }
3427 UNREACHABLE(); 3323 UNREACHABLE();
3428 return nullptr; 3324 return nullptr;
3429 } 3325 }
3430 3326
3431 Node* AstGraphBuilder::BuildVariableAssignment( 3327 Node* AstGraphBuilder::BuildVariableAssignment(
3432 Variable* variable, Node* value, Token::Value op, 3328 Variable* variable, Node* value, Token::Value op,
3433 const VectorSlotPair& feedback, BailoutId bailout_id, 3329 const VectorSlotPair& feedback, BailoutId bailout_id,
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3527 javascript()->LoadContext(depth, variable->index(), false); 3423 javascript()->LoadContext(depth, variable->index(), false);
3528 Node* current = NewNode(op, current_context()); 3424 Node* current = NewNode(op, current_context());
3529 BuildHoleCheckThenThrow(current, variable, value, bailout_id); 3425 BuildHoleCheckThenThrow(current, variable, value, bailout_id);
3530 } 3426 }
3531 // Assignment to const is exception in all modes. 3427 // Assignment to const is exception in all modes.
3532 return BuildThrowConstAssignError(bailout_id); 3428 return BuildThrowConstAssignError(bailout_id);
3533 } 3429 }
3534 const Operator* op = javascript()->StoreContext(depth, variable->index()); 3430 const Operator* op = javascript()->StoreContext(depth, variable->index());
3535 return NewNode(op, current_context(), value); 3431 return NewNode(op, current_context(), value);
3536 } 3432 }
3537 case VariableLocation::LOOKUP: { 3433 case VariableLocation::LOOKUP:
3538 // Dynamic lookup of context variable (anywhere in the chain).
3539 Handle<Name> name = variable->name();
3540 Node* store = BuildDynamicStore(name, value);
3541 PrepareFrameState(store, bailout_id, combine);
3542 return store;
3543 }
3544 case VariableLocation::MODULE: 3434 case VariableLocation::MODULE:
3545 UNREACHABLE(); 3435 UNREACHABLE();
3546 } 3436 }
3547 UNREACHABLE(); 3437 UNREACHABLE();
3548 return nullptr; 3438 return nullptr;
3549 } 3439 }
3550 3440
3551 3441
3552 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key, 3442 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
3553 const VectorSlotPair& feedback) { 3443 const VectorSlotPair& feedback) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3635 3525
3636 3526
3637 Node* AstGraphBuilder::BuildGlobalStore(Handle<Name> name, Node* value, 3527 Node* AstGraphBuilder::BuildGlobalStore(Handle<Name> name, Node* value,
3638 const VectorSlotPair& feedback) { 3528 const VectorSlotPair& feedback) {
3639 const Operator* op = 3529 const Operator* op =
3640 javascript()->StoreGlobal(language_mode(), name, feedback); 3530 javascript()->StoreGlobal(language_mode(), name, feedback);
3641 Node* node = NewNode(op, value, GetFunctionClosure()); 3531 Node* node = NewNode(op, value, GetFunctionClosure());
3642 return node; 3532 return node;
3643 } 3533 }
3644 3534
3645
3646 Node* AstGraphBuilder::BuildDynamicLoad(Handle<Name> name,
3647 TypeofMode typeof_mode) {
3648 Node* name_node = jsgraph()->Constant(name);
3649 const Operator* op =
3650 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
3651 ? Runtime::kLoadLookupSlot
3652 : Runtime::kLoadLookupSlotInsideTypeof);
3653 Node* node = NewNode(op, name_node);
3654 return node;
3655 }
3656
3657
3658 Node* AstGraphBuilder::BuildDynamicStore(Handle<Name> name, Node* value) {
3659 Node* name_node = jsgraph()->Constant(name);
3660 const Operator* op = javascript()->CallRuntime(
3661 is_strict(language_mode()) ? Runtime::kStoreLookupSlot_Strict
3662 : Runtime::kStoreLookupSlot_Sloppy);
3663 Node* node = NewNode(op, name_node, value);
3664 return node;
3665 }
3666
3667
3668 Node* AstGraphBuilder::BuildLoadGlobalObject() { 3535 Node* AstGraphBuilder::BuildLoadGlobalObject() {
3669 return BuildLoadNativeContextField(Context::EXTENSION_INDEX); 3536 return BuildLoadNativeContextField(Context::EXTENSION_INDEX);
3670 } 3537 }
3671 3538
3672 3539
3673 Node* AstGraphBuilder::BuildLoadNativeContextField(int index) { 3540 Node* AstGraphBuilder::BuildLoadNativeContextField(int index) {
3674 const Operator* op = 3541 const Operator* op =
3675 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true); 3542 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
3676 Node* native_context = NewNode(op, current_context()); 3543 Node* native_context = NewNode(op, current_context());
3677 return NewNode(javascript()->LoadContext(0, index, true), native_context); 3544 return NewNode(javascript()->LoadContext(0, index, true), native_context);
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
3844 } 3711 }
3845 3712
3846 3713
3847 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { 3714 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) {
3848 // Optimize global constants like "undefined", "Infinity", and "NaN". 3715 // Optimize global constants like "undefined", "Infinity", and "NaN".
3849 Handle<Object> constant_value = isolate()->factory()->GlobalConstantFor(name); 3716 Handle<Object> constant_value = isolate()->factory()->GlobalConstantFor(name);
3850 if (!constant_value.is_null()) return jsgraph()->Constant(constant_value); 3717 if (!constant_value.is_null()) return jsgraph()->Constant(constant_value);
3851 return nullptr; 3718 return nullptr;
3852 } 3719 }
3853 3720
3854 Node* AstGraphBuilder::TryLoadDynamicVariable(Variable* variable,
3855 Handle<String> name,
3856 BailoutId bailout_id,
3857 const VectorSlotPair& feedback,
3858 OutputFrameStateCombine combine,
3859 TypeofMode typeof_mode) {
3860 VariableMode mode = variable->mode();
3861
3862 if (mode == DYNAMIC_GLOBAL) {
3863 uint32_t bitset = ComputeBitsetForDynamicGlobal(variable);
3864 if (bitset == kFullCheckRequired) return nullptr;
3865
3866 // We are using two blocks to model fast and slow cases.
3867 BlockBuilder fast_block(this);
3868 BlockBuilder slow_block(this);
3869 environment()->Push(jsgraph()->TheHoleConstant());
3870 slow_block.BeginBlock();
3871 environment()->Pop();
3872 fast_block.BeginBlock();
3873
3874 // Perform checks whether the fast mode applies, by looking for any
3875 // extension object which might shadow the optimistic declaration.
3876 for (int depth = 0; bitset != 0; bitset >>= 1, depth++) {
3877 if ((bitset & 1) == 0) continue;
3878 Node* load = NewNode(
3879 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
3880 current_context());
3881 Node* check =
3882 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), load,
3883 jsgraph()->TheHoleConstant());
3884 fast_block.BreakUnless(check, BranchHint::kTrue);
3885 }
3886
3887 // Fast case, because variable is not shadowed.
3888 if (Node* constant = TryLoadGlobalConstant(name)) {
3889 environment()->Push(constant);
3890 } else {
3891 // Perform global slot load.
3892 Node* fast = BuildGlobalLoad(name, feedback, typeof_mode);
3893 PrepareFrameState(fast, bailout_id, combine);
3894 environment()->Push(fast);
3895 }
3896 slow_block.Break();
3897 environment()->Pop();
3898 fast_block.EndBlock();
3899
3900 // Slow case, because variable potentially shadowed. Perform dynamic lookup.
3901 Node* slow = BuildDynamicLoad(name, typeof_mode);
3902 PrepareFrameState(slow, bailout_id, combine);
3903 environment()->Push(slow);
3904 slow_block.EndBlock();
3905
3906 return environment()->Pop();
3907 }
3908
3909 if (mode == DYNAMIC_LOCAL) {
3910 uint32_t bitset = ComputeBitsetForDynamicContext(variable);
3911 if (bitset == kFullCheckRequired) return nullptr;
3912
3913 // We are using two blocks to model fast and slow cases.
3914 BlockBuilder fast_block(this);
3915 BlockBuilder slow_block(this);
3916 environment()->Push(jsgraph()->TheHoleConstant());
3917 slow_block.BeginBlock();
3918 environment()->Pop();
3919 fast_block.BeginBlock();
3920
3921 // Perform checks whether the fast mode applies, by looking for any
3922 // extension object which might shadow the optimistic declaration.
3923 for (int depth = 0; bitset != 0; bitset >>= 1, depth++) {
3924 if ((bitset & 1) == 0) continue;
3925 Node* load = NewNode(
3926 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
3927 current_context());
3928 Node* check =
3929 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), load,
3930 jsgraph()->TheHoleConstant());
3931 fast_block.BreakUnless(check, BranchHint::kTrue);
3932 }
3933
3934 // Fast case, because variable is not shadowed. Perform context slot load.
3935 Variable* local = variable->local_if_not_shadowed();
3936 DCHECK(local->location() == VariableLocation::CONTEXT); // Must be context.
3937 Node* fast =
3938 BuildVariableLoad(local, bailout_id, feedback, combine, typeof_mode);
3939 environment()->Push(fast);
3940 slow_block.Break();
3941 environment()->Pop();
3942 fast_block.EndBlock();
3943
3944 // Slow case, because variable potentially shadowed. Perform dynamic lookup.
3945 Node* slow = BuildDynamicLoad(name, typeof_mode);
3946 PrepareFrameState(slow, bailout_id, combine);
3947 environment()->Push(slow);
3948 slow_block.EndBlock();
3949
3950 return environment()->Pop();
3951 }
3952
3953 return nullptr;
3954 }
3955
3956
3957 Node* AstGraphBuilder::TryFastToBoolean(Node* input) { 3721 Node* AstGraphBuilder::TryFastToBoolean(Node* input) {
3958 switch (input->opcode()) { 3722 switch (input->opcode()) {
3959 case IrOpcode::kNumberConstant: { 3723 case IrOpcode::kNumberConstant: {
3960 NumberMatcher m(input); 3724 NumberMatcher m(input);
3961 return jsgraph_->BooleanConstant(!m.Is(0) && !m.IsNaN()); 3725 return jsgraph_->BooleanConstant(!m.Is(0) && !m.IsNaN());
3962 } 3726 }
3963 case IrOpcode::kHeapConstant: { 3727 case IrOpcode::kHeapConstant: {
3964 Handle<HeapObject> object = HeapObjectMatcher(input).Value(); 3728 Handle<HeapObject> object = HeapObjectMatcher(input).Value();
3965 return jsgraph_->BooleanConstant(object->BooleanValue()); 3729 return jsgraph_->BooleanConstant(object->BooleanValue());
3966 } 3730 }
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
4368 TypeHintAnalysis* type_hint_analysis, SourcePositionTable* source_positions, 4132 TypeHintAnalysis* type_hint_analysis, SourcePositionTable* source_positions,
4369 int inlining_id) 4133 int inlining_id)
4370 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency, 4134 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency,
4371 loop_assignment, type_hint_analysis), 4135 loop_assignment, type_hint_analysis),
4372 source_positions_(source_positions), 4136 source_positions_(source_positions),
4373 start_position_(info->shared_info()->start_position(), inlining_id) {} 4137 start_position_(info->shared_info()->start_position(), inlining_id) {}
4374 4138
4375 } // namespace compiler 4139 } // namespace compiler
4376 } // namespace internal 4140 } // namespace internal
4377 } // namespace v8 4141 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/full-codegen/arm/full-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698