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

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

Issue 161853002: Enable polymorphic inlining of StringBase [] and StringBase codeUnitAt (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 case MethodRecognizer::kByteArrayBaseSetFloat32x4: 1396 case MethodRecognizer::kByteArrayBaseSetFloat32x4:
1397 if (!ShouldInlineSimd()) return false; 1397 if (!ShouldInlineSimd()) return false;
1398 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, 1398 return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
1399 kTypedDataFloat32x4ArrayCid, 1399 kTypedDataFloat32x4ArrayCid,
1400 ic_data, entry, last); 1400 ic_data, entry, last);
1401 case MethodRecognizer::kByteArrayBaseSetInt32x4: 1401 case MethodRecognizer::kByteArrayBaseSetInt32x4:
1402 if (!ShouldInlineSimd()) return false; 1402 if (!ShouldInlineSimd()) return false;
1403 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, 1403 return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
1404 kTypedDataInt32x4ArrayCid, 1404 kTypedDataInt32x4ArrayCid,
1405 ic_data, entry, last); 1405 ic_data, entry, last);
1406 case MethodRecognizer::kStringBaseCodeUnitAt:
1407 return InlineStringCodeUnitAt(call, receiver_cid, entry, last);
1408 case MethodRecognizer::kStringBaseCharAt:
1409 return InlineStringBaseCharAt(call, receiver_cid, entry, last);
1406 default: 1410 default:
1407 return false; 1411 return false;
1408 } 1412 }
1409 } 1413 }
1410 1414
1411 1415
1412 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call, 1416 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call,
1413 intptr_t array_cid, 1417 intptr_t array_cid,
1414 Definition** array, 1418 Definition** array,
1415 Definition* index, 1419 Definition* index,
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after
2404 if (target.kind() != RawFunction::kImplicitGetter) { 2408 if (target.kind() != RawFunction::kImplicitGetter) {
2405 // Non-implicit getters are inlined like normal methods by conventional 2409 // Non-implicit getters are inlined like normal methods by conventional
2406 // inlining in FlowGraphInliner. 2410 // inlining in FlowGraphInliner.
2407 return false; 2411 return false;
2408 } 2412 }
2409 InlineImplicitInstanceGetter(call); 2413 InlineImplicitInstanceGetter(call);
2410 return true; 2414 return true;
2411 } 2415 }
2412 2416
2413 2417
2414 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt( 2418 bool FlowGraphOptimizer::TryReplaceInstanceCallWithInline(
2415 InstanceCallInstr* call, 2419 InstanceCallInstr* call) {
2416 intptr_t cid) { 2420 ASSERT(call->HasICData());
2417 Definition* str = call->ArgumentAt(0); 2421 Function& target = Function::Handle();
2418 Definition* index = call->ArgumentAt(1); 2422 GrowableArray<intptr_t> class_ids;
2423 call->ic_data()->GetCheckAt(0, &class_ids, &target);
2424 const intptr_t receiver_cid = class_ids[0];
2425
2426 TargetEntryInstr* entry;
2427 Definition* last;
2428 if (!TryInlineRecognizedMethod(receiver_cid,
2429 target,
2430 call,
2431 call->ArgumentAt(0),
2432 call->token_pos(),
2433 *call->ic_data(),
2434 &entry, &last)) {
2435 return false;
2436 }
2437
2438 // Insert receiver class check.
2419 AddReceiverCheck(call); 2439 AddReceiverCheck(call);
2420 InsertBefore(call, 2440 // Remove the original push arguments.
2421 new CheckSmiInstr(new Value(index), call->deopt_id()), 2441 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
2422 call->env(), 2442 PushArgumentInstr* push = call->PushArgumentAt(i);
2423 Definition::kEffect); 2443 push->ReplaceUsesWith(push->value()->definition());
2424 // If both index and string are constants, then do a compile-time check. 2444 push->RemoveFromGraph();
2425 // TODO(srdjan): Remove once constant propagation handles bounds checks.
2426 bool skip_check = false;
2427 if (str->IsConstant() && index->IsConstant()) {
2428 const String& constant_string =
2429 String::Cast(str->AsConstant()->value());
2430 const Object& constant_index = index->AsConstant()->value();
2431 skip_check = constant_index.IsSmi() &&
2432 (Smi::Cast(constant_index).Value() < constant_string.Length());
2433 } 2445 }
2434 if (!skip_check) { 2446 // Replace all uses of this definition with the result.
2435 // Insert bounds check. 2447 call->ReplaceUsesWith(last);
2436 LoadFieldInstr* length = BuildLoadStringLength(str); 2448 // Finally insert the sequence other definition in place of this one in the
2437 InsertBefore(call, length, NULL, Definition::kValue); 2449 // graph.
2438 InsertBefore(call, 2450 call->previous()->LinkTo(entry->next());
2439 new CheckArrayBoundInstr(new Value(length), 2451 entry->UnuseAllInputs(); // Entry block is not in the graph.
2440 new Value(index), 2452 last->LinkTo(call);
2441 call->deopt_id()), 2453 // Remove through the iterator.
2442 call->env(), 2454 ASSERT(current_iterator()->Current() == call);
2443 Definition::kEffect); 2455 current_iterator()->RemoveCurrentFromGraph();
2444 } 2456 call->set_previous(NULL);
2445 return new LoadIndexedInstr(new Value(str), 2457 call->set_next(NULL);
2446 new Value(index), 2458 return true;
2447 FlowGraphCompiler::ElementSizeFor(cid),
2448 cid,
2449 Isolate::kNoDeoptId); // Can't deoptimize.
2450 } 2459 }
2451 2460
2452 2461
2462 // Returns the LoadIndexedInstr.
2463 Definition* FlowGraphOptimizer::PrepareInlineStringIndexOp(
2464 Instruction* call,
2465 intptr_t cid,
2466 Definition* str,
2467 Definition* index,
2468 Instruction* cursor) {
2469
2470 cursor = flow_graph()->AppendTo(cursor,
2471 new CheckSmiInstr(new Value(index),
2472 call->deopt_id()),
2473 call->env(),
2474 Definition::kEffect);
2475
2476 // Load the length of the string.
2477 LoadFieldInstr* length = BuildLoadStringLength(str);
2478 cursor = flow_graph()->AppendTo(cursor, length, NULL, Definition::kValue);
2479 // Bounds check.
2480 cursor = flow_graph()->AppendTo(cursor,
2481 new CheckArrayBoundInstr(new Value(length),
2482 new Value(index),
2483 call->deopt_id()),
2484 call->env(),
2485 Definition::kEffect);
2486
2487 LoadIndexedInstr* load_indexed = new LoadIndexedInstr(
2488 new Value(str),
2489 new Value(index),
2490 FlowGraphCompiler::ElementSizeFor(cid),
2491 cid,
2492 Isolate::kNoDeoptId);
2493
2494 cursor = flow_graph()->AppendTo(cursor,
2495 load_indexed,
2496 NULL,
2497 Definition::kValue);
2498 ASSERT(cursor == load_indexed);
2499 return load_indexed;
2500 }
2501
2502
2503 bool FlowGraphOptimizer::InlineStringCodeUnitAt(
2504 Instruction* call,
2505 intptr_t cid,
2506 TargetEntryInstr** entry,
2507 Definition** last) {
2508 if (RawObject::IsExternalStringClassId(cid)) {
Florian Schneider 2014/02/17 11:56:12 Add a TODO for handling external strings in the sa
Cutch 2014/02/18 17:00:30 Done.
2509 return false;
2510 }
2511
2512 Definition* str = call->ArgumentAt(0);
2513 Definition* index = call->ArgumentAt(1);
2514
2515 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
2516 call->GetBlock()->try_index());
2517 (*entry)->InheritDeoptTarget(call);
2518
2519 *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry);
2520
2521 return true;
2522 }
2523
2524
2525 bool FlowGraphOptimizer::InlineStringBaseCharAt(
2526 Instruction* call,
2527 intptr_t cid,
2528 TargetEntryInstr** entry,
2529 Definition** last) {
2530 if (RawObject::IsExternalStringClassId(cid) || cid != kOneByteStringCid) {
Florian Schneider 2014/02/17 11:56:12 Add a TODO for handling external strings in the sa
Cutch 2014/02/18 17:00:30 Done.
2531 return false;
2532 }
2533 Definition* str = call->ArgumentAt(0);
2534 Definition* index = call->ArgumentAt(1);
2535
2536 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
2537 call->GetBlock()->try_index());
2538 (*entry)->InheritDeoptTarget(call);
2539
2540 *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry);
2541
2542 StringFromCharCodeInstr* char_at =
2543 new StringFromCharCodeInstr(new Value(*last), cid);
2544
2545 flow_graph()->AppendTo(*last, char_at, NULL, Definition::kValue);
2546 *last = char_at;
2547
2548 return true;
2549 }
2550
2551
2453 void FlowGraphOptimizer::ReplaceWithMathCFunction( 2552 void FlowGraphOptimizer::ReplaceWithMathCFunction(
2454 InstanceCallInstr* call, 2553 InstanceCallInstr* call,
2455 MethodRecognizer::Kind recognized_kind) { 2554 MethodRecognizer::Kind recognized_kind) {
2456 AddReceiverCheck(call); 2555 AddReceiverCheck(call);
2457 ZoneGrowableArray<Value*>* args = 2556 ZoneGrowableArray<Value*>* args =
2458 new ZoneGrowableArray<Value*>(call->ArgumentCount()); 2557 new ZoneGrowableArray<Value*>(call->ArgumentCount());
2459 for (intptr_t i = 0; i < call->ArgumentCount(); i++) { 2558 for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
2460 args->Add(new Value(call->ArgumentAt(i))); 2559 args->Add(new Value(call->ArgumentAt(i)));
2461 } 2560 }
2462 InvokeMathCFunctionInstr* invoke = 2561 InvokeMathCFunctionInstr* invoke =
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2526 Definition* value = call->ArgumentAt(1); 2625 Definition* value = call->ArgumentAt(1);
2527 StoreVMFieldInstr* store = new StoreVMFieldInstr( 2626 StoreVMFieldInstr* store = new StoreVMFieldInstr(
2528 new Value(array), 2627 new Value(array),
2529 GrowableObjectArray::length_offset(), 2628 GrowableObjectArray::length_offset(),
2530 new Value(value), 2629 new Value(value),
2531 Type::ZoneHandle()); 2630 Type::ZoneHandle());
2532 ReplaceCall(call, store); 2631 ReplaceCall(call, store);
2533 return true; 2632 return true;
2534 } 2633 }
2535 2634
2536 if ((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) && 2635 if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) ||
2636 (recognized_kind == MethodRecognizer::kStringBaseCharAt)) &&
2537 (ic_data.NumberOfChecks() == 1) && 2637 (ic_data.NumberOfChecks() == 1) &&
2538 ((class_ids[0] == kOneByteStringCid) || 2638 ((class_ids[0] == kOneByteStringCid) ||
2539 (class_ids[0] == kTwoByteStringCid))) { 2639 (class_ids[0] == kTwoByteStringCid))) {
2540 LoadIndexedInstr* instr = BuildStringCodeUnitAt(call, class_ids[0]); 2640 return TryReplaceInstanceCallWithInline(call);
2541 ReplaceCall(call, instr);
2542 return true;
2543 } 2641 }
2642
2544 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) { 2643 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
2545 if (recognized_kind == MethodRecognizer::kStringBaseCharAt) {
2546 // TODO(fschneider): Handle TwoByteString.
2547 LoadIndexedInstr* load_char_code =
2548 BuildStringCodeUnitAt(call, class_ids[0]);
2549 InsertBefore(call, load_char_code, NULL, Definition::kValue);
2550 StringFromCharCodeInstr* char_at =
2551 new StringFromCharCodeInstr(new Value(load_char_code),
2552 kOneByteStringCid);
2553 ReplaceCall(call, char_at);
2554 return true;
2555 }
2556 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) { 2644 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) {
2557 // This is an internal method, no need to check argument types nor 2645 // This is an internal method, no need to check argument types nor
2558 // range. 2646 // range.
2559 Definition* str = call->ArgumentAt(0); 2647 Definition* str = call->ArgumentAt(0);
2560 Definition* index = call->ArgumentAt(1); 2648 Definition* index = call->ArgumentAt(1);
2561 Definition* value = call->ArgumentAt(2); 2649 Definition* value = call->ArgumentAt(2);
2562 StoreIndexedInstr* store_op = new StoreIndexedInstr( 2650 StoreIndexedInstr* store_op = new StoreIndexedInstr(
2563 new Value(str), 2651 new Value(str),
2564 new Value(index), 2652 new Value(index),
2565 new Value(value), 2653 new Value(value),
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
3289 } 3377 }
3290 3378
3291 3379
3292 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call, 3380 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call,
3293 intptr_t view_cid) { 3381 intptr_t view_cid) {
3294 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || 3382 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) ||
3295 (view_cid == kTypedDataInt32x4ArrayCid); 3383 (view_cid == kTypedDataInt32x4ArrayCid);
3296 if (simd_view && !ShouldInlineSimd()) { 3384 if (simd_view && !ShouldInlineSimd()) {
3297 return false; 3385 return false;
3298 } 3386 }
3299 3387 return TryReplaceInstanceCallWithInline(call);
3300 ASSERT(call->HasICData());
3301 Function& target = Function::Handle();
3302 GrowableArray<intptr_t> class_ids;
3303 call->ic_data()->GetCheckAt(0, &class_ids, &target);
3304 const intptr_t receiver_cid = class_ids[0];
3305
3306 TargetEntryInstr* entry;
3307 Definition* last;
3308 if (!TryInlineRecognizedMethod(receiver_cid,
3309 target,
3310 call,
3311 call->ArgumentAt(0),
3312 call->token_pos(),
3313 *call->ic_data(),
3314 &entry, &last)) {
3315 return false;
3316 }
3317
3318 // Insert receiver class check.
3319 AddReceiverCheck(call);
3320 // Remove the original push arguments.
3321 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
3322 PushArgumentInstr* push = call->PushArgumentAt(i);
3323 push->ReplaceUsesWith(push->value()->definition());
3324 push->RemoveFromGraph();
3325 }
3326 // Replace all uses of this definition with the result.
3327 call->ReplaceUsesWith(last);
3328 // Finally insert the sequence other definition in place of this one in the
3329 // graph.
3330 call->previous()->LinkTo(entry->next());
3331 entry->UnuseAllInputs(); // Entry block is not in the graph.
3332 last->LinkTo(call);
3333 // Remove through the iterator.
3334 ASSERT(current_iterator()->Current() == call);
3335 current_iterator()->RemoveCurrentFromGraph();
3336 call->set_previous(NULL);
3337 call->set_next(NULL);
3338 return true;
3339 } 3388 }
3340 3389
3341 3390
3342 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call, 3391 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call,
3343 intptr_t view_cid) { 3392 intptr_t view_cid) {
3344 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || 3393 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) ||
3345 (view_cid == kTypedDataInt32x4ArrayCid); 3394 (view_cid == kTypedDataInt32x4ArrayCid);
3346 if (simd_view && !ShouldInlineSimd()) { 3395 if (simd_view && !ShouldInlineSimd()) {
3347 return false; 3396 return false;
3348 } 3397 }
3349 ASSERT(call->HasICData()); 3398 return TryReplaceInstanceCallWithInline(call);
3350 Function& target = Function::Handle();
3351 GrowableArray<intptr_t> class_ids;
3352 call->ic_data()->GetCheckAt(0, &class_ids, &target);
3353 const intptr_t receiver_cid = class_ids[0];
3354
3355 TargetEntryInstr* entry;
3356 Definition* last;
3357 if (!TryInlineRecognizedMethod(receiver_cid,
3358 target,
3359 call,
3360 call->ArgumentAt(0),
3361 call->token_pos(),
3362 *call->ic_data(),
3363 &entry, &last)) {
3364 return false;
3365 }
3366
3367 // Insert receiver class check.
3368 AddReceiverCheck(call);
3369 // Remove the original push arguments.
3370 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
3371 PushArgumentInstr* push = call->PushArgumentAt(i);
3372 push->ReplaceUsesWith(push->value()->definition());
3373 push->RemoveFromGraph();
3374 }
3375 // Replace all uses of this definition with the result.
3376 call->ReplaceUsesWith(last);
3377 // Finally insert the sequence other definition in place of this one in the
3378 // graph.
3379 call->previous()->LinkTo(entry->next());
3380 entry->UnuseAllInputs(); // Entry block is not in the graph.
3381 last->LinkTo(call);
3382 // Remove through the iterator.
3383 ASSERT(current_iterator()->Current() == call);
3384 current_iterator()->RemoveCurrentFromGraph();
3385 call->set_previous(NULL);
3386 call->set_next(NULL);
3387 return true;
3388 } 3399 }
3389 3400
3390 3401
3391 void FlowGraphOptimizer::PrepareByteArrayViewOp(
3392 InstanceCallInstr* call,
3393 intptr_t receiver_cid,
3394 intptr_t view_cid,
3395 Definition** array) {
3396 Definition* byte_index = call->ArgumentAt(1);
3397
3398 AddReceiverCheck(call);
3399 const bool is_immutable = true;
3400 LoadFieldInstr* length = new LoadFieldInstr(
3401 new Value(*array),
3402 CheckArrayBoundInstr::LengthOffsetFor(receiver_cid),
3403 Type::ZoneHandle(Type::SmiType()),
3404 is_immutable);
3405 length->set_result_cid(kSmiCid);
3406 length->set_recognized_kind(
3407 LoadFieldInstr::RecognizedKindFromArrayCid(receiver_cid));
3408 InsertBefore(call, length, NULL, Definition::kValue);
3409
3410 // len_in_bytes = length * kBytesPerElement(receiver)
3411 intptr_t element_size = FlowGraphCompiler::ElementSizeFor(receiver_cid);
3412 ConstantInstr* bytes_per_element =
3413 flow_graph()->GetConstant(Smi::Handle(Smi::New(element_size)));
3414 BinarySmiOpInstr* len_in_bytes =
3415 new BinarySmiOpInstr(Token::kMUL,
3416 new Value(length),
3417 new Value(bytes_per_element),
3418 call->deopt_id());
3419 InsertBefore(call, len_in_bytes, call->env(), Definition::kValue);
3420
3421 ConstantInstr* length_adjustment =
3422 flow_graph()->GetConstant(Smi::Handle(Smi::New(
3423 FlowGraphCompiler::ElementSizeFor(view_cid) - 1)));
3424 // adjusted_length = len_in_bytes - (element_size - 1).
3425 BinarySmiOpInstr* adjusted_length =
3426 new BinarySmiOpInstr(Token::kSUB,
3427 new Value(len_in_bytes),
3428 new Value(length_adjustment),
3429 call->deopt_id());
3430 InsertBefore(call, adjusted_length, call->env(), Definition::kValue);
3431 // Check adjusted_length > 0.
3432 ConstantInstr* zero = flow_graph()->GetConstant(Smi::Handle(Smi::New(0)));
3433 InsertBefore(call,
3434 new CheckArrayBoundInstr(new Value(adjusted_length),
3435 new Value(zero),
3436 call->deopt_id()),
3437 call->env(),
3438 Definition::kEffect);
3439 // Check 0 <= byte_index < adjusted_length.
3440 InsertBefore(call,
3441 new CheckArrayBoundInstr(new Value(adjusted_length),
3442 new Value(byte_index),
3443 call->deopt_id()),
3444 call->env(),
3445 Definition::kEffect);
3446
3447 // Insert load of elements for external typed arrays.
3448 if (RawObject::IsExternalTypedDataClassId(receiver_cid)) {
3449 LoadUntaggedInstr* elements =
3450 new LoadUntaggedInstr(new Value(*array),
3451 ExternalTypedData::data_offset());
3452 InsertBefore(call, elements, NULL, Definition::kValue);
3453 *array = elements;
3454 }
3455 }
3456
3457
3458 // Returns a Boolean constant if all classes in ic_data yield the same type-test 3402 // Returns a Boolean constant if all classes in ic_data yield the same type-test
3459 // result and the type tests do not depend on type arguments. Otherwise return 3403 // result and the type tests do not depend on type arguments. Otherwise return
3460 // Bool::null(). 3404 // Bool::null().
3461 RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data, 3405 RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data,
3462 const AbstractType& type) const { 3406 const AbstractType& type) const {
3463 ASSERT(ic_data.num_args_tested() == 1); // Unary checks only. 3407 ASSERT(ic_data.num_args_tested() == 1); // Unary checks only.
3464 if (!type.IsInstantiated() || type.IsMalformedOrMalbounded()) { 3408 if (!type.IsInstantiated() || type.IsMalformedOrMalbounded()) {
3465 return Bool::null(); 3409 return Bool::null();
3466 } 3410 }
3467 const Class& type_class = Class::Handle(type.type_class()); 3411 const Class& type_class = Class::Handle(type.type_class());
(...skipping 5142 matching lines...) Expand 10 before | Expand all | Expand 10 after
8610 } 8554 }
8611 8555
8612 // Insert materializations at environment uses. 8556 // Insert materializations at environment uses.
8613 for (intptr_t i = 0; i < exits.length(); i++) { 8557 for (intptr_t i = 0; i < exits.length(); i++) {
8614 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 8558 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
8615 } 8559 }
8616 } 8560 }
8617 8561
8618 8562
8619 } // namespace dart 8563 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698