| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 3250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3261 } | 3261 } |
| 3262 | 3262 |
| 3263 | 3263 |
| 3264 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope) { | 3264 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope) { |
| 3265 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), | 3265 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), |
| 3266 true); // Test only. | 3266 true); // Test only. |
| 3267 return new(Z) LoadLocalInstr(*receiver_var); | 3267 return new(Z) LoadLocalInstr(*receiver_var); |
| 3268 } | 3268 } |
| 3269 | 3269 |
| 3270 | 3270 |
| 3271 LoadFieldInstr* EffectGraphVisitor::BuildNativeGetter( |
| 3272 NativeBodyNode* node, |
| 3273 MethodRecognizer::Kind kind, |
| 3274 intptr_t offset, |
| 3275 const Type& type, |
| 3276 intptr_t class_id) { |
| 3277 Value* receiver = Bind(BuildLoadThisVar(node->scope())); |
| 3278 LoadFieldInstr* load = new(Z) LoadFieldInstr(receiver, |
| 3279 offset, |
| 3280 type, |
| 3281 node->token_pos()); |
| 3282 load->set_result_cid(class_id); |
| 3283 load->set_recognized_kind(kind); |
| 3284 return load; |
| 3285 } |
| 3286 |
| 3287 |
| 3271 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { | 3288 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { |
| 3272 const Function& function = owner()->function(); | 3289 const Function& function = owner()->function(); |
| 3273 if (!function.IsClosureFunction()) { | 3290 if (!function.IsClosureFunction()) { |
| 3274 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); | 3291 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); |
| 3275 switch (kind) { | 3292 switch (kind) { |
| 3276 case MethodRecognizer::kObjectEquals: { | 3293 case MethodRecognizer::kObjectEquals: { |
| 3277 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3294 Value* receiver = Bind(BuildLoadThisVar(node->scope())); |
| 3278 LocalVariable* other_var = | 3295 LocalVariable* other_var = |
| 3279 node->scope()->LookupVariable(Symbols::Other(), | 3296 node->scope()->LookupVariable(Symbols::Other(), |
| 3280 true); // Test only. | 3297 true); // Test only. |
| 3281 Value* other = Bind(new(Z) LoadLocalInstr(*other_var)); | 3298 Value* other = Bind(new(Z) LoadLocalInstr(*other_var)); |
| 3282 // Receiver is not a number because numbers override equality. | 3299 // Receiver is not a number because numbers override equality. |
| 3283 const bool kNoNumberCheck = false; | 3300 const bool kNoNumberCheck = false; |
| 3284 StrictCompareInstr* compare = | 3301 StrictCompareInstr* compare = |
| 3285 new(Z) StrictCompareInstr(node->token_pos(), | 3302 new(Z) StrictCompareInstr(node->token_pos(), |
| 3286 Token::kEQ_STRICT, | 3303 Token::kEQ_STRICT, |
| 3287 receiver, | 3304 receiver, |
| 3288 other, | 3305 other, |
| 3289 kNoNumberCheck); | 3306 kNoNumberCheck); |
| 3290 return ReturnDefinition(compare); | 3307 return ReturnDefinition(compare); |
| 3291 } | 3308 } |
| 3292 case MethodRecognizer::kStringBaseLength: | 3309 case MethodRecognizer::kStringBaseLength: |
| 3293 case MethodRecognizer::kStringBaseIsEmpty: { | 3310 case MethodRecognizer::kStringBaseIsEmpty: { |
| 3294 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | |
| 3295 // Treat length loads as mutable (i.e. affected by side effects) to | 3311 // Treat length loads as mutable (i.e. affected by side effects) to |
| 3296 // avoid hoisting them since we can't hoist the preceding class-check. | 3312 // avoid hoisting them since we can't hoist the preceding class-check. |
| 3297 // This is because of externalization of strings that affects their | 3313 // This is because of externalization of strings that affects their |
| 3298 // class-id. | 3314 // class-id. |
| 3299 LoadFieldInstr* load = new(Z) LoadFieldInstr( | 3315 LoadFieldInstr* load = BuildNativeGetter( |
| 3300 receiver, | 3316 node, MethodRecognizer::kStringBaseLength, String::length_offset(), |
| 3301 String::length_offset(), | 3317 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); |
| 3302 Type::ZoneHandle(Z, Type::SmiType()), | |
| 3303 node->token_pos()); | |
| 3304 load->set_result_cid(kSmiCid); | |
| 3305 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); | |
| 3306 if (kind == MethodRecognizer::kStringBaseLength) { | 3318 if (kind == MethodRecognizer::kStringBaseLength) { |
| 3307 return ReturnDefinition(load); | 3319 return ReturnDefinition(load); |
| 3308 } | 3320 } |
| 3309 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); | 3321 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); |
| 3310 Value* zero_val = Bind(new(Z) ConstantInstr( | 3322 Value* zero_val = Bind(new(Z) ConstantInstr( |
| 3311 Smi::ZoneHandle(Z, Smi::New(0)))); | 3323 Smi::ZoneHandle(Z, Smi::New(0)))); |
| 3312 Value* load_val = Bind(load); | 3324 Value* load_val = Bind(load); |
| 3313 StrictCompareInstr* compare = | 3325 StrictCompareInstr* compare = |
| 3314 new(Z) StrictCompareInstr(node->token_pos(), | 3326 new(Z) StrictCompareInstr(node->token_pos(), |
| 3315 Token::kEQ_STRICT, | 3327 Token::kEQ_STRICT, |
| 3316 load_val, | 3328 load_val, |
| 3317 zero_val, | 3329 zero_val, |
| 3318 false); // No number check. | 3330 false); // No number check. |
| 3319 return ReturnDefinition(compare); | 3331 return ReturnDefinition(compare); |
| 3320 } | 3332 } |
| 3321 case MethodRecognizer::kGrowableArrayLength: | 3333 case MethodRecognizer::kGrowableArrayLength: |
| 3322 case MethodRecognizer::kObjectArrayLength: | 3334 case MethodRecognizer::kObjectArrayLength: |
| 3323 case MethodRecognizer::kImmutableArrayLength: | 3335 case MethodRecognizer::kImmutableArrayLength: |
| 3324 case MethodRecognizer::kTypedDataLength: { | 3336 case MethodRecognizer::kTypedDataLength: { |
| 3325 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3337 LoadFieldInstr* load = BuildNativeGetter( |
| 3326 LoadFieldInstr* load = new(Z) LoadFieldInstr( | 3338 node, kind, OffsetForLengthGetter(kind), |
| 3327 receiver, | 3339 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); |
| 3328 OffsetForLengthGetter(kind), | |
| 3329 Type::ZoneHandle(Z, Type::SmiType()), | |
| 3330 node->token_pos()); | |
| 3331 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength); | 3340 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength); |
| 3332 load->set_result_cid(kSmiCid); | |
| 3333 load->set_recognized_kind(kind); | |
| 3334 return ReturnDefinition(load); | 3341 return ReturnDefinition(load); |
| 3335 } | 3342 } |
| 3336 case MethodRecognizer::kClassIDgetID: { | 3343 case MethodRecognizer::kClassIDgetID: { |
| 3337 LocalVariable* value_var = | 3344 LocalVariable* value_var = |
| 3338 node->scope()->LookupVariable(Symbols::Value(), true); | 3345 node->scope()->LookupVariable(Symbols::Value(), true); |
| 3339 Value* value = Bind(new(Z) LoadLocalInstr(*value_var)); | 3346 Value* value = Bind(new(Z) LoadLocalInstr(*value_var)); |
| 3340 LoadClassIdInstr* load = new(Z) LoadClassIdInstr(value); | 3347 LoadClassIdInstr* load = new(Z) LoadClassIdInstr(value); |
| 3341 return ReturnDefinition(load); | 3348 return ReturnDefinition(load); |
| 3342 } | 3349 } |
| 3343 case MethodRecognizer::kGrowableArrayCapacity: { | 3350 case MethodRecognizer::kGrowableArrayCapacity: { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3364 true); | 3371 true); |
| 3365 Value* element_type = Bind(new(Z) LoadLocalInstr(*type_args_parameter)); | 3372 Value* element_type = Bind(new(Z) LoadLocalInstr(*type_args_parameter)); |
| 3366 LocalVariable* length_parameter = | 3373 LocalVariable* length_parameter = |
| 3367 node->scope()->LookupVariable(Symbols::Length(), true); | 3374 node->scope()->LookupVariable(Symbols::Length(), true); |
| 3368 Value* length = Bind(new(Z) LoadLocalInstr(*length_parameter)); | 3375 Value* length = Bind(new(Z) LoadLocalInstr(*length_parameter)); |
| 3369 CreateArrayInstr* create_array = | 3376 CreateArrayInstr* create_array = |
| 3370 new CreateArrayInstr(node->token_pos(), element_type, length); | 3377 new CreateArrayInstr(node->token_pos(), element_type, length); |
| 3371 return ReturnDefinition(create_array); | 3378 return ReturnDefinition(create_array); |
| 3372 } | 3379 } |
| 3373 case MethodRecognizer::kBigint_getDigits: { | 3380 case MethodRecognizer::kBigint_getDigits: { |
| 3374 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3381 return ReturnDefinition(BuildNativeGetter( |
| 3375 LoadFieldInstr* load = new(Z) LoadFieldInstr( | 3382 node, kind, Bigint::digits_offset(), |
| 3376 receiver, | |
| 3377 Bigint::digits_offset(), | |
| 3378 Type::ZoneHandle(Z, Type::DynamicType()), | 3383 Type::ZoneHandle(Z, Type::DynamicType()), |
| 3379 node->token_pos()); | 3384 kTypedDataUint32ArrayCid)); |
| 3380 load->set_result_cid(kTypedDataUint32ArrayCid); | |
| 3381 load->set_recognized_kind(kind); | |
| 3382 return ReturnDefinition(load); | |
| 3383 } | 3385 } |
| 3384 case MethodRecognizer::kBigint_getUsed: { | 3386 case MethodRecognizer::kBigint_getUsed: { |
| 3385 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3387 return ReturnDefinition(BuildNativeGetter( |
| 3386 LoadFieldInstr* load = new(Z) LoadFieldInstr( | 3388 node, kind, Bigint::used_offset(), |
| 3387 receiver, | 3389 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid)); |
| 3388 Bigint::used_offset(), | |
| 3389 Type::ZoneHandle(Z, Type::SmiType()), | |
| 3390 node->token_pos()); | |
| 3391 load->set_result_cid(kSmiCid); | |
| 3392 load->set_recognized_kind(kind); | |
| 3393 return ReturnDefinition(load); | |
| 3394 } | 3390 } |
| 3395 case MethodRecognizer::kBigint_getNeg: { | 3391 case MethodRecognizer::kBigint_getNeg: { |
| 3396 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3392 return ReturnDefinition(BuildNativeGetter( |
| 3397 LoadFieldInstr* load = new(Z) LoadFieldInstr( | 3393 node, kind, Bigint::neg_offset(), |
| 3398 receiver, | 3394 Type::ZoneHandle(Z, Type::BoolType()), kBoolCid)); |
| 3399 Bigint::neg_offset(), | |
| 3400 Type::ZoneHandle(Z, Type::BoolType()), | |
| 3401 node->token_pos()); | |
| 3402 load->set_result_cid(kBoolCid); | |
| 3403 load->set_recognized_kind(kind); | |
| 3404 return ReturnDefinition(load); | |
| 3405 } | 3395 } |
| 3406 default: | 3396 default: |
| 3407 break; | 3397 break; |
| 3408 } | 3398 } |
| 3409 } | 3399 } |
| 3410 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); | 3400 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); |
| 3411 NativeCallInstr* native_call = new(Z) NativeCallInstr(node); | 3401 NativeCallInstr* native_call = new(Z) NativeCallInstr(node); |
| 3412 ReturnDefinition(native_call); | 3402 ReturnDefinition(native_call); |
| 3413 } | 3403 } |
| 3414 | 3404 |
| (...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4377 Report::MessageF(Report::kBailout, | 4367 Report::MessageF(Report::kBailout, |
| 4378 Script::Handle(function.script()), | 4368 Script::Handle(function.script()), |
| 4379 function.token_pos(), | 4369 function.token_pos(), |
| 4380 "FlowGraphBuilder Bailout: %s %s", | 4370 "FlowGraphBuilder Bailout: %s %s", |
| 4381 String::Handle(function.name()).ToCString(), | 4371 String::Handle(function.name()).ToCString(), |
| 4382 reason); | 4372 reason); |
| 4383 UNREACHABLE(); | 4373 UNREACHABLE(); |
| 4384 } | 4374 } |
| 4385 | 4375 |
| 4386 } // namespace dart | 4376 } // namespace dart |
| OLD | NEW |