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

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

Issue 9373025: Optimizing code generator expects that every AST node is traversed once, i.e., the nodes are not ... (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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
« no previous file with comments | « no previous file | runtime/vm/parser.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 (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/opt_code_generator.h" 8 #include "vm/opt_code_generator.h"
9 9
10 #include "vm/assembler_macros.h" 10 #include "vm/assembler_macros.h"
(...skipping 2465 matching lines...) Expand 10 before | Expand all | Expand 10 after
2476 } 2476 }
2477 CodeGenerator::VisitLoadIndexedNode(node); 2477 CodeGenerator::VisitLoadIndexedNode(node);
2478 } 2478 }
2479 2479
2480 2480
2481 void OptimizingCodeGenerator::VisitStoreIndexedNode(StoreIndexedNode* node) { 2481 void OptimizingCodeGenerator::VisitStoreIndexedNode(StoreIndexedNode* node) {
2482 if (FLAG_enable_type_checks) { 2482 if (FLAG_enable_type_checks) {
2483 CodeGenerator::VisitStoreIndexedNode(node); 2483 CodeGenerator::VisitStoreIndexedNode(node);
2484 return; 2484 return;
2485 } 2485 }
2486 node->array()->Visit(this); 2486 Class& known_array_class = Class::Handle();
2487 // Load array and release its CodeGenInfo as value may refer to the same
2488 // array (e.g. in a[x] += 3). Fixes issue 1570.
2489 {
2490 CodeGenInfo array_info(node->array());
2491 node->array()->Visit(this);
2492 known_array_class = array_info.is_class()->raw();
hausner 2012/02/09 21:51:48 Not sure why you call this the "known" array class
srdjan 2012/02/10 07:13:11 Changing it to class_of_this_array to avoid confus
2493 }
2487 // TODO(srdjan): Use VisitLoadTwo and check if index is smi (CodeGenInfo). 2494 // TODO(srdjan): Use VisitLoadTwo and check if index is smi (CodeGenInfo).
2488 ObjectStore* object_store = Isolate::Current()->object_store(); 2495 ObjectStore* object_store = Isolate::Current()->object_store();
2489 const Class& object_array_class = 2496 const Class& object_array_class =
2490 Class::ZoneHandle(object_store->array_class()); 2497 Class::ZoneHandle(object_store->array_class());
2491 const ICData& ic_data = node->ICDataAtId(node->id()); 2498 const ICData& ic_data = node->ICDataAtId(node->id());
2492 if (ic_data.NumberOfChecks() == 0) { 2499 if (ic_data.NumberOfChecks() == 0) {
2493 VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX); 2500 VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX);
2494 DeoptimizationBlob* deopt_blob = 2501 DeoptimizationBlob* deopt_blob =
2495 AddDeoptimizationBlob(node, EBX, ECX, kDeoptNoTypeFeedback); 2502 AddDeoptimizationBlob(node, EBX, ECX, kDeoptNoTypeFeedback);
2496 __ jmp(deopt_blob->label()); 2503 __ jmp(deopt_blob->label());
2497 return; 2504 return;
2498 } 2505 }
2499 2506
2500 CodeGenInfo array_info(node->array());
2501 CodeGenInfo index_info(node->index_expr());
2502 2507
2503 if (AtIdNodeHasClassAt(node, node->id(), object_array_class, 0)) { 2508 if (AtIdNodeHasClassAt(node, node->id(), object_array_class, 0)) {
2504 VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX); 2509 // Release CodeGenInfo of index quickly as it may be used in the value,
2510 // e.g. a[i] += 3. Fixes issue 1570.
2511 bool index_is_smi = false;
2512 {
2513 CodeGenInfo index_info(node->index_expr());
2514 node->index_expr()->Visit(this);
2515 index_is_smi = index_info.IsClass(smi_class_);
2516 }
2517 VisitLoadOne(node->value(), ECX);
2505 DeoptimizationBlob* deopt_blob = 2518 DeoptimizationBlob* deopt_blob =
2506 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed); 2519 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed);
2520 __ popl(EBX); // index.
2507 __ popl(EAX); // array. 2521 __ popl(EAX); // array.
2508 // ECX: value, EBX:index, EAX: array. 2522 // ECX: value, EBX:index, EAX: array.
2509 // Check class of array. 2523 // Check class of array.
2510 if (!array_info.IsClass(object_array_class)) { 2524 if (known_array_class.raw() != object_array_class.raw()) {
2511 __ testl(EAX, Immediate(kSmiTagMask)); 2525 __ testl(EAX, Immediate(kSmiTagMask));
2512 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt. 2526 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt.
2513 __ movl(EDX, FieldAddress(EAX, Object::class_offset())); 2527 __ movl(EDX, FieldAddress(EAX, Object::class_offset()));
2514 __ CompareObject(EDX, object_array_class); 2528 __ CompareObject(EDX, object_array_class);
2515 __ j(NOT_EQUAL, deopt_blob->label()); // Not ObjectArray -> deopt. 2529 __ j(NOT_EQUAL, deopt_blob->label()); // Not ObjectArray -> deopt.
2516 PropagateBackLocalClass(node->array(), object_array_class); 2530 PropagateBackLocalClass(node->array(), object_array_class);
2517 } 2531 }
2518 // Check class of index. 2532 // Check class of index.
2519 if (!index_info.IsClass(smi_class_)) { 2533 if (!index_is_smi) {
2520 __ testl(EBX, Immediate(kSmiTagMask)); 2534 __ testl(EBX, Immediate(kSmiTagMask));
2521 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt. 2535 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
2522 PropagateBackLocalClass(node->index_expr(), smi_class_); 2536 PropagateBackLocalClass(node->index_expr(), smi_class_);
2523 } 2537 }
2524 // Range check. 2538 // Range check.
2525 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); 2539 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset()));
2526 __ j(ABOVE_EQUAL, deopt_blob->label()); // Range error -> deopt. 2540 __ j(ABOVE_EQUAL, deopt_blob->label()); // Range error -> deopt.
2527 ASSERT(kSmiTagShift == 1); 2541 ASSERT(kSmiTagShift == 1);
2528 __ StoreIntoObject(EAX, 2542 __ StoreIntoObject(EAX,
2529 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), 2543 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)),
(...skipping 10 matching lines...) Expand all
2540 ASSERT(!growable_array_class.IsNull()); 2554 ASSERT(!growable_array_class.IsNull());
2541 if (AtIdNodeHasClassAt(node, node->id(), growable_array_class, 0)) { 2555 if (AtIdNodeHasClassAt(node, node->id(), growable_array_class, 0)) {
2542 const String& growable_array_length_field_name = 2556 const String& growable_array_length_field_name =
2543 String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName)); 2557 String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName));
2544 const String& growable_array_array_field_name = 2558 const String& growable_array_array_field_name =
2545 String::Handle(String::NewSymbol(kGrowableArrayArrayFieldName)); 2559 String::Handle(String::NewSymbol(kGrowableArrayArrayFieldName));
2546 intptr_t length_offset = GetFieldOffset(growable_array_class, 2560 intptr_t length_offset = GetFieldOffset(growable_array_class,
2547 growable_array_length_field_name); 2561 growable_array_length_field_name);
2548 intptr_t array_offset = GetFieldOffset(growable_array_class, 2562 intptr_t array_offset = GetFieldOffset(growable_array_class,
2549 growable_array_array_field_name); 2563 growable_array_array_field_name);
2550 VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX); 2564 bool index_is_smi = false;
2565 // Release CodeGenInfo of index quickly as it may be used in the value,
2566 // e.g. a[i] += 3. Fixes issue 1570.
2567 {
2568 CodeGenInfo index_info(node->index_expr());
2569 node->index_expr()->Visit(this);
2570 index_is_smi = index_info.IsClass(smi_class_);
2571 }
2572 VisitLoadOne(node->value(), ECX);
2551 DeoptimizationBlob* deopt_blob = 2573 DeoptimizationBlob* deopt_blob =
2552 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed); 2574 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed);
2553 __ popl(EAX); // Array. 2575 __ popl(EBX); // index.
2576 __ popl(EAX); // array.
2554 // ECX: value, EBX:index, EAX: array, EDX: scratch. 2577 // ECX: value, EBX:index, EAX: array, EDX: scratch.
2555 // Check class of array. 2578 // Check class of array.
2556 if (!array_info.IsClass(growable_array_class)) { 2579 if (known_array_class.raw() != growable_array_class.raw()) {
2557 __ testl(EAX, Immediate(kSmiTagMask)); 2580 __ testl(EAX, Immediate(kSmiTagMask));
2558 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt. 2581 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt.
2559 __ movl(EDX, FieldAddress(EAX, Object::class_offset())); 2582 __ movl(EDX, FieldAddress(EAX, Object::class_offset()));
2560 __ CompareObject(EDX, growable_array_class); 2583 __ CompareObject(EDX, growable_array_class);
2561 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray. 2584 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray.
2562 PropagateBackLocalClass(node->array(), growable_array_class); 2585 PropagateBackLocalClass(node->array(), growable_array_class);
2563 } 2586 }
2564 // Check class of index. 2587 // Check class of index.
2565 if (!index_info.IsClass(smi_class_)) { 2588 if (!index_is_smi) {
2566 __ testl(EBX, Immediate(kSmiTagMask)); 2589 __ testl(EBX, Immediate(kSmiTagMask));
2567 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt. 2590 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
2568 PropagateBackLocalClass(node->index_expr(), smi_class_); 2591 PropagateBackLocalClass(node->index_expr(), smi_class_);
2569 } 2592 }
2570 // Range check: deoptimize if out of bounds. 2593 // Range check: deoptimize if out of bounds.
2571 __ cmpl(EBX, FieldAddress(EAX, length_offset)); 2594 __ cmpl(EBX, FieldAddress(EAX, length_offset));
2572 __ j(ABOVE_EQUAL, deopt_blob->label()); 2595 __ j(ABOVE_EQUAL, deopt_blob->label());
2573 __ movl(EDX, FieldAddress(EAX, array_offset)); // backingArray. 2596 __ movl(EDX, FieldAddress(EAX, array_offset)); // backingArray.
2574 // Note that EAX is Smi, i.e, times 2. 2597 // Note that EAX is Smi, i.e, times 2.
2575 ASSERT(kSmiTagShift == 1); 2598 ASSERT(kSmiTagShift == 1);
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
3123 } 3146 }
3124 } 3147 }
3125 // TODO(srdjan): Implement unary kSUB (negate) Mint. 3148 // TODO(srdjan): Implement unary kSUB (negate) Mint.
3126 CodeGenerator::VisitUnaryOpNode(node); 3149 CodeGenerator::VisitUnaryOpNode(node);
3127 } 3150 }
3128 3151
3129 3152
3130 } // namespace dart 3153 } // namespace dart
3131 3154
3132 #endif // defined TARGET_ARCH_IA32 3155 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698