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

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 1124963002: Share code for building recognized native getters. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 7 months 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 19 matching lines...) Expand all
3363 node->scope()->LookupVariable(Symbols::TypeArgumentsParameter(), 3370 node->scope()->LookupVariable(Symbols::TypeArgumentsParameter(),
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: {
Florian Schneider 2015/05/05 23:47:01 It seems you can also use the new helper for getDi
koda 2015/05/06 00:20:44 Done. Thanks.
3374 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3381 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3375 LoadFieldInstr* load = new(Z) LoadFieldInstr( 3382 LoadFieldInstr* load = new(Z) LoadFieldInstr(
3376 receiver, 3383 receiver,
3377 Bigint::digits_offset(), 3384 Bigint::digits_offset(),
3378 Type::ZoneHandle(Z, Type::DynamicType()), 3385 Type::ZoneHandle(Z, Type::DynamicType()),
3379 node->token_pos()); 3386 node->token_pos());
3380 load->set_result_cid(kTypedDataUint32ArrayCid); 3387 load->set_result_cid(kTypedDataUint32ArrayCid);
3381 load->set_recognized_kind(kind); 3388 load->set_recognized_kind(kind);
3382 return ReturnDefinition(load); 3389 return ReturnDefinition(load);
3383 } 3390 }
3384 case MethodRecognizer::kBigint_getUsed: { 3391 case MethodRecognizer::kBigint_getUsed: {
3385 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3392 return ReturnDefinition(BuildNativeGetter(
3386 LoadFieldInstr* load = new(Z) LoadFieldInstr( 3393 node, kind, Bigint::used_offset(),
3387 receiver, 3394 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 } 3395 }
3395 case MethodRecognizer::kBigint_getNeg: { 3396 case MethodRecognizer::kBigint_getNeg: {
3396 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3397 return ReturnDefinition(BuildNativeGetter(
3397 LoadFieldInstr* load = new(Z) LoadFieldInstr( 3398 node, kind, Bigint::neg_offset(),
3398 receiver, 3399 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 } 3400 }
3406 default: 3401 default:
3407 break; 3402 break;
3408 } 3403 }
3409 } 3404 }
3410 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); 3405 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode");
3411 NativeCallInstr* native_call = new(Z) NativeCallInstr(node); 3406 NativeCallInstr* native_call = new(Z) NativeCallInstr(node);
3412 ReturnDefinition(native_call); 3407 ReturnDefinition(native_call);
3413 } 3408 }
3414 3409
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after
4377 Report::MessageF(Report::kBailout, 4372 Report::MessageF(Report::kBailout,
4378 Script::Handle(function.script()), 4373 Script::Handle(function.script()),
4379 function.token_pos(), 4374 function.token_pos(),
4380 "FlowGraphBuilder Bailout: %s %s", 4375 "FlowGraphBuilder Bailout: %s %s",
4381 String::Handle(function.name()).ToCString(), 4376 String::Handle(function.name()).ToCString(),
4382 reason); 4377 reason);
4383 UNREACHABLE(); 4378 UNREACHABLE();
4384 } 4379 }
4385 4380
4386 } // namespace dart 4381 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698