OLD | NEW |
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/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
(...skipping 2111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2122 BuildVariableLoad(states, proxy->var(), expr->target()->id(), pair, | 2122 BuildVariableLoad(states, proxy->var(), expr->target()->id(), pair, |
2123 OutputFrameStateCombine::Push()); | 2123 OutputFrameStateCombine::Push()); |
2124 break; | 2124 break; |
2125 } | 2125 } |
2126 case NAMED_PROPERTY: { | 2126 case NAMED_PROPERTY: { |
2127 Node* object = environment()->Top(); | 2127 Node* object = environment()->Top(); |
2128 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2128 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2129 VectorSlotPair pair = | 2129 VectorSlotPair pair = |
2130 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2130 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2131 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2131 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2132 old_value = | 2132 old_value = BuildNamedLoad(object, name, pair); |
2133 BuildNamedLoad(object, name, pair, property->PropertyFeedbackId()); | |
2134 states.AddToNode(old_value, property->LoadId(), | 2133 states.AddToNode(old_value, property->LoadId(), |
2135 OutputFrameStateCombine::Push()); | 2134 OutputFrameStateCombine::Push()); |
2136 break; | 2135 break; |
2137 } | 2136 } |
2138 case KEYED_PROPERTY: { | 2137 case KEYED_PROPERTY: { |
2139 Node* key = environment()->Top(); | 2138 Node* key = environment()->Top(); |
2140 Node* object = environment()->Peek(1); | 2139 Node* object = environment()->Peek(1); |
2141 VectorSlotPair pair = | 2140 VectorSlotPair pair = |
2142 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2141 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2143 FrameStateBeforeAndAfter states(this, property->key()->id()); | 2142 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2144 old_value = | 2143 old_value = BuildKeyedLoad(object, key, pair); |
2145 BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId()); | |
2146 states.AddToNode(old_value, property->LoadId(), | 2144 states.AddToNode(old_value, property->LoadId(), |
2147 OutputFrameStateCombine::Push()); | 2145 OutputFrameStateCombine::Push()); |
2148 break; | 2146 break; |
2149 } | 2147 } |
2150 } | 2148 } |
2151 environment()->Push(old_value); | 2149 environment()->Push(old_value); |
2152 VisitForValue(expr->value()); | 2150 VisitForValue(expr->value()); |
2153 Node* value; | 2151 Node* value; |
2154 { | 2152 { |
2155 FrameStateBeforeAndAfter states(this, expr->value()->id()); | 2153 FrameStateBeforeAndAfter states(this, expr->value()->id()); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2220 | 2218 |
2221 | 2219 |
2222 void AstGraphBuilder::VisitProperty(Property* expr) { | 2220 void AstGraphBuilder::VisitProperty(Property* expr) { |
2223 Node* value; | 2221 Node* value; |
2224 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); | 2222 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); |
2225 if (expr->key()->IsPropertyName()) { | 2223 if (expr->key()->IsPropertyName()) { |
2226 VisitForValue(expr->obj()); | 2224 VisitForValue(expr->obj()); |
2227 FrameStateBeforeAndAfter states(this, expr->obj()->id()); | 2225 FrameStateBeforeAndAfter states(this, expr->obj()->id()); |
2228 Node* object = environment()->Pop(); | 2226 Node* object = environment()->Pop(); |
2229 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); | 2227 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); |
2230 value = BuildNamedLoad(object, name, pair, expr->PropertyFeedbackId()); | 2228 value = BuildNamedLoad(object, name, pair); |
2231 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2229 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
2232 } else { | 2230 } else { |
2233 VisitForValue(expr->obj()); | 2231 VisitForValue(expr->obj()); |
2234 VisitForValue(expr->key()); | 2232 VisitForValue(expr->key()); |
2235 FrameStateBeforeAndAfter states(this, expr->key()->id()); | 2233 FrameStateBeforeAndAfter states(this, expr->key()->id()); |
2236 Node* key = environment()->Pop(); | 2234 Node* key = environment()->Pop(); |
2237 Node* object = environment()->Pop(); | 2235 Node* object = environment()->Pop(); |
2238 value = BuildKeyedLoad(object, key, pair, expr->PropertyFeedbackId()); | 2236 value = BuildKeyedLoad(object, key, pair); |
2239 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2237 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
2240 } | 2238 } |
2241 ast_context()->ProduceValue(value); | 2239 ast_context()->ProduceValue(value); |
2242 } | 2240 } |
2243 | 2241 |
2244 | 2242 |
2245 void AstGraphBuilder::VisitCall(Call* expr) { | 2243 void AstGraphBuilder::VisitCall(Call* expr) { |
2246 Expression* callee = expr->expression(); | 2244 Expression* callee = expr->expression(); |
2247 Call::CallType call_type = expr->GetCallType(isolate()); | 2245 Call::CallType call_type = expr->GetCallType(isolate()); |
2248 | 2246 |
(...skipping 30 matching lines...) Expand all Loading... |
2279 } | 2277 } |
2280 case Call::PROPERTY_CALL: { | 2278 case Call::PROPERTY_CALL: { |
2281 Property* property = callee->AsProperty(); | 2279 Property* property = callee->AsProperty(); |
2282 VisitForValue(property->obj()); | 2280 VisitForValue(property->obj()); |
2283 Node* object = environment()->Top(); | 2281 Node* object = environment()->Top(); |
2284 VectorSlotPair pair = | 2282 VectorSlotPair pair = |
2285 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2283 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2286 if (property->key()->IsPropertyName()) { | 2284 if (property->key()->IsPropertyName()) { |
2287 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2285 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2288 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2286 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2289 callee_value = | 2287 callee_value = BuildNamedLoad(object, name, pair); |
2290 BuildNamedLoad(object, name, pair, property->PropertyFeedbackId()); | |
2291 states.AddToNode(callee_value, property->LoadId(), | 2288 states.AddToNode(callee_value, property->LoadId(), |
2292 OutputFrameStateCombine::Push()); | 2289 OutputFrameStateCombine::Push()); |
2293 } else { | 2290 } else { |
2294 VisitForValue(property->key()); | 2291 VisitForValue(property->key()); |
2295 FrameStateBeforeAndAfter states(this, property->key()->id()); | 2292 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2296 Node* key = environment()->Pop(); | 2293 Node* key = environment()->Pop(); |
2297 callee_value = | 2294 callee_value = BuildKeyedLoad(object, key, pair); |
2298 BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId()); | |
2299 states.AddToNode(callee_value, property->LoadId(), | 2295 states.AddToNode(callee_value, property->LoadId(), |
2300 OutputFrameStateCombine::Push()); | 2296 OutputFrameStateCombine::Push()); |
2301 } | 2297 } |
2302 receiver_value = environment()->Pop(); | 2298 receiver_value = environment()->Pop(); |
2303 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an | 2299 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an |
2304 // object for sloppy callees. This could also be modeled explicitly here, | 2300 // object for sloppy callees. This could also be modeled explicitly here, |
2305 // thereby obsoleting the need for a flag to the call operator. | 2301 // thereby obsoleting the need for a flag to the call operator. |
2306 flags = CALL_AS_METHOD; | 2302 flags = CALL_AS_METHOD; |
2307 break; | 2303 break; |
2308 } | 2304 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2403 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { | 2399 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { |
2404 Handle<String> name = expr->name(); | 2400 Handle<String> name = expr->name(); |
2405 | 2401 |
2406 // The callee and the receiver both have to be pushed onto the operand stack | 2402 // The callee and the receiver both have to be pushed onto the operand stack |
2407 // before arguments are being evaluated. | 2403 // before arguments are being evaluated. |
2408 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 2404 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; |
2409 Node* receiver_value = BuildLoadBuiltinsObject(); | 2405 Node* receiver_value = BuildLoadBuiltinsObject(); |
2410 VectorSlotPair pair = CreateVectorSlotPair(expr->CallRuntimeFeedbackSlot()); | 2406 VectorSlotPair pair = CreateVectorSlotPair(expr->CallRuntimeFeedbackSlot()); |
2411 // TODO(jarin): bailout ids for runtime calls. | 2407 // TODO(jarin): bailout ids for runtime calls. |
2412 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 2408 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
2413 Node* callee_value = | 2409 Node* callee_value = BuildNamedLoad(receiver_value, name, pair); |
2414 BuildNamedLoad(receiver_value, name, pair, expr->CallRuntimeFeedbackId()); | |
2415 states.AddToNode(callee_value, BailoutId::None(), | 2410 states.AddToNode(callee_value, BailoutId::None(), |
2416 OutputFrameStateCombine::Push()); | 2411 OutputFrameStateCombine::Push()); |
2417 environment()->Push(callee_value); | 2412 environment()->Push(callee_value); |
2418 environment()->Push(receiver_value); | 2413 environment()->Push(receiver_value); |
2419 | 2414 |
2420 // Evaluate all arguments to the JS runtime call. | 2415 // Evaluate all arguments to the JS runtime call. |
2421 ZoneList<Expression*>* args = expr->arguments(); | 2416 ZoneList<Expression*>* args = expr->arguments(); |
2422 VisitForValues(args); | 2417 VisitForValues(args); |
2423 | 2418 |
2424 // Create node to perform the JS runtime call. | 2419 // Create node to perform the JS runtime call. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2494 stack_depth = 0; | 2489 stack_depth = 0; |
2495 break; | 2490 break; |
2496 } | 2491 } |
2497 case NAMED_PROPERTY: { | 2492 case NAMED_PROPERTY: { |
2498 VisitForValue(property->obj()); | 2493 VisitForValue(property->obj()); |
2499 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2494 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2500 Node* object = environment()->Top(); | 2495 Node* object = environment()->Top(); |
2501 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2496 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2502 VectorSlotPair pair = | 2497 VectorSlotPair pair = |
2503 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2498 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2504 old_value = | 2499 old_value = BuildNamedLoad(object, name, pair); |
2505 BuildNamedLoad(object, name, pair, property->PropertyFeedbackId()); | |
2506 states.AddToNode(old_value, property->LoadId(), | 2500 states.AddToNode(old_value, property->LoadId(), |
2507 OutputFrameStateCombine::Push()); | 2501 OutputFrameStateCombine::Push()); |
2508 stack_depth = 1; | 2502 stack_depth = 1; |
2509 break; | 2503 break; |
2510 } | 2504 } |
2511 case KEYED_PROPERTY: { | 2505 case KEYED_PROPERTY: { |
2512 VisitForValue(property->obj()); | 2506 VisitForValue(property->obj()); |
2513 VisitForValue(property->key()); | 2507 VisitForValue(property->key()); |
2514 FrameStateBeforeAndAfter states(this, property->key()->id()); | 2508 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2515 Node* key = environment()->Top(); | 2509 Node* key = environment()->Top(); |
2516 Node* object = environment()->Peek(1); | 2510 Node* object = environment()->Peek(1); |
2517 VectorSlotPair pair = | 2511 VectorSlotPair pair = |
2518 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2512 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2519 old_value = | 2513 old_value = BuildKeyedLoad(object, key, pair); |
2520 BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId()); | |
2521 states.AddToNode(old_value, property->LoadId(), | 2514 states.AddToNode(old_value, property->LoadId(), |
2522 OutputFrameStateCombine::Push()); | 2515 OutputFrameStateCombine::Push()); |
2523 stack_depth = 2; | 2516 stack_depth = 2; |
2524 break; | 2517 break; |
2525 } | 2518 } |
2526 } | 2519 } |
2527 | 2520 |
2528 // Convert old value into a number. | 2521 // Convert old value into a number. |
2529 old_value = NewNode(javascript()->ToNumber(), old_value); | 2522 old_value = NewNode(javascript()->ToNumber(), old_value); |
2530 PrepareFrameState(old_value, expr->ToNumberId(), | 2523 PrepareFrameState(old_value, expr->ToNumberId(), |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3005 const VectorSlotPair& feedback, | 2998 const VectorSlotPair& feedback, |
3006 OutputFrameStateCombine combine, | 2999 OutputFrameStateCombine combine, |
3007 ContextualMode contextual_mode) { | 3000 ContextualMode contextual_mode) { |
3008 Node* the_hole = jsgraph()->TheHoleConstant(); | 3001 Node* the_hole = jsgraph()->TheHoleConstant(); |
3009 VariableMode mode = variable->mode(); | 3002 VariableMode mode = variable->mode(); |
3010 switch (variable->location()) { | 3003 switch (variable->location()) { |
3011 case Variable::UNALLOCATED: { | 3004 case Variable::UNALLOCATED: { |
3012 // Global var, const, or let variable. | 3005 // Global var, const, or let variable. |
3013 Node* global = BuildLoadGlobalObject(); | 3006 Node* global = BuildLoadGlobalObject(); |
3014 Handle<Name> name = variable->name(); | 3007 Handle<Name> name = variable->name(); |
3015 Node* node = BuildNamedLoad(global, name, feedback, | 3008 Node* node = BuildNamedLoad(global, name, feedback, contextual_mode); |
3016 TypeFeedbackId::None(), contextual_mode); | |
3017 states.AddToNode(node, bailout_id, combine); | 3009 states.AddToNode(node, bailout_id, combine); |
3018 return node; | 3010 return node; |
3019 } | 3011 } |
3020 case Variable::PARAMETER: | 3012 case Variable::PARAMETER: |
3021 case Variable::LOCAL: { | 3013 case Variable::LOCAL: { |
3022 // Local var, const, or let variable. | 3014 // Local var, const, or let variable. |
3023 Node* value = environment()->Lookup(variable); | 3015 Node* value = environment()->Lookup(variable); |
3024 if (mode == CONST_LEGACY) { | 3016 if (mode == CONST_LEGACY) { |
3025 // Perform check for uninitialized legacy const variables. | 3017 // Perform check for uninitialized legacy const variables. |
3026 if (value->op() == the_hole->op()) { | 3018 if (value->op() == the_hole->op()) { |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3211 PrepareFrameState(store, bailout_id, combine); | 3203 PrepareFrameState(store, bailout_id, combine); |
3212 return store; | 3204 return store; |
3213 } | 3205 } |
3214 } | 3206 } |
3215 UNREACHABLE(); | 3207 UNREACHABLE(); |
3216 return NULL; | 3208 return NULL; |
3217 } | 3209 } |
3218 | 3210 |
3219 | 3211 |
3220 static inline Node* Record(JSTypeFeedbackTable* js_type_feedback, Node* node, | 3212 static inline Node* Record(JSTypeFeedbackTable* js_type_feedback, Node* node, |
3221 TypeFeedbackId id, FeedbackVectorICSlot slot) { | 3213 FeedbackVectorICSlot slot) { |
3222 if (js_type_feedback) { | 3214 if (js_type_feedback) { |
3223 js_type_feedback->Record(node, id); | |
3224 js_type_feedback->Record(node, slot); | 3215 js_type_feedback->Record(node, slot); |
3225 } | 3216 } |
3226 return node; | 3217 return node; |
3227 } | 3218 } |
3228 | 3219 |
3229 | 3220 |
| 3221 static inline Node* Record(JSTypeFeedbackTable* js_type_feedback, Node* node, |
| 3222 TypeFeedbackId id) { |
| 3223 if (js_type_feedback) { |
| 3224 js_type_feedback->Record(node, id); |
| 3225 } |
| 3226 return node; |
| 3227 } |
| 3228 |
| 3229 |
3230 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key, | 3230 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key, |
3231 const VectorSlotPair& feedback, | 3231 const VectorSlotPair& feedback) { |
3232 TypeFeedbackId id) { | |
3233 const Operator* op = javascript()->LoadProperty(feedback); | 3232 const Operator* op = javascript()->LoadProperty(feedback); |
3234 return Record(js_type_feedback_, NewNode(op, object, key), id, | 3233 return Record(js_type_feedback_, NewNode(op, object, key), feedback.slot()); |
3235 feedback.slot()); | |
3236 } | 3234 } |
3237 | 3235 |
3238 | 3236 |
3239 Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name, | 3237 Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name, |
3240 const VectorSlotPair& feedback, | 3238 const VectorSlotPair& feedback, |
3241 TypeFeedbackId id, ContextualMode mode) { | 3239 ContextualMode mode) { |
3242 const Operator* op = | 3240 const Operator* op = |
3243 javascript()->LoadNamed(MakeUnique(name), feedback, mode); | 3241 javascript()->LoadNamed(MakeUnique(name), feedback, mode); |
3244 return Record(js_type_feedback_, NewNode(op, object), id, feedback.slot()); | 3242 return Record(js_type_feedback_, NewNode(op, object), feedback.slot()); |
3245 } | 3243 } |
3246 | 3244 |
3247 | 3245 |
3248 Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value, | 3246 Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value, |
3249 TypeFeedbackId id) { | 3247 TypeFeedbackId id) { |
3250 const Operator* op = javascript()->StoreProperty(language_mode()); | 3248 const Operator* op = javascript()->StoreProperty(language_mode()); |
3251 return Record(js_type_feedback_, NewNode(op, object, key, value), id, | 3249 return Record(js_type_feedback_, NewNode(op, object, key, value), id); |
3252 FeedbackVectorICSlot::Invalid()); | |
3253 } | 3250 } |
3254 | 3251 |
3255 | 3252 |
3256 Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name, | 3253 Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name, |
3257 Node* value, TypeFeedbackId id) { | 3254 Node* value, TypeFeedbackId id) { |
3258 const Operator* op = | 3255 const Operator* op = |
3259 javascript()->StoreNamed(language_mode(), MakeUnique(name)); | 3256 javascript()->StoreNamed(language_mode(), MakeUnique(name)); |
3260 return Record(js_type_feedback_, NewNode(op, object, value), id, | 3257 return Record(js_type_feedback_, NewNode(op, object, value), id); |
3261 FeedbackVectorICSlot::Invalid()); | |
3262 } | 3258 } |
3263 | 3259 |
3264 | 3260 |
3265 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) { | 3261 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) { |
3266 return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, | 3262 return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, |
3267 jsgraph()->IntPtrConstant(offset - kHeapObjectTag)); | 3263 jsgraph()->IntPtrConstant(offset - kHeapObjectTag)); |
3268 } | 3264 } |
3269 | 3265 |
3270 | 3266 |
3271 Node* AstGraphBuilder::BuildLoadBuiltinsObject() { | 3267 Node* AstGraphBuilder::BuildLoadBuiltinsObject() { |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3778 // Phi does not exist yet, introduce one. | 3774 // Phi does not exist yet, introduce one. |
3779 value = NewPhi(inputs, value, control); | 3775 value = NewPhi(inputs, value, control); |
3780 value->ReplaceInput(inputs - 1, other); | 3776 value->ReplaceInput(inputs - 1, other); |
3781 } | 3777 } |
3782 return value; | 3778 return value; |
3783 } | 3779 } |
3784 | 3780 |
3785 } // namespace compiler | 3781 } // namespace compiler |
3786 } // namespace internal | 3782 } // namespace internal |
3787 } // namespace v8 | 3783 } // namespace v8 |
OLD | NEW |