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

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

Issue 9020030: Optimize indexed store for growable array (intrinsification and inlined optimized). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years 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/intrinsifier_ia32.cc ('k') | tests/language/src/OptimizationTest.dart » ('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 2342 matching lines...) Expand 10 before | Expand all | Expand 10 after
2353 } 2353 }
2354 TraceOpt(node, kMessage); 2354 TraceOpt(node, kMessage);
2355 return; 2355 return;
2356 } 2356 }
2357 2357
2358 const String& growable_object_array_class_name = String::Handle( 2358 const String& growable_object_array_class_name = String::Handle(
2359 String::NewSymbol(kGrowableArrayClassName)); 2359 String::NewSymbol(kGrowableArrayClassName));
2360 const Class& growable_array_class = Class::ZoneHandle( 2360 const Class& growable_array_class = Class::ZoneHandle(
2361 Library::Handle(Library::CoreImplLibrary()). 2361 Library::Handle(Library::CoreImplLibrary()).
2362 LookupClass(growable_object_array_class_name)); 2362 LookupClass(growable_object_array_class_name));
2363 ASSERT(!growable_array_class.IsNull());
2363 if (AtIdNodeHasOnlyClass(node, node->id(), growable_array_class)) { 2364 if (AtIdNodeHasOnlyClass(node, node->id(), growable_array_class)) {
2364 const String& growable_array_length_field_name = 2365 const String& growable_array_length_field_name =
2365 String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName)); 2366 String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName));
2366 const String& growable_array_array_field_name = 2367 const String& growable_array_array_field_name =
2367 String::Handle(String::NewSymbol(kGrowableArrayArrayFieldName)); 2368 String::Handle(String::NewSymbol(kGrowableArrayArrayFieldName));
2368 intptr_t length_offset = GetFieldOffset(growable_array_class, 2369 intptr_t length_offset = GetFieldOffset(growable_array_class,
2369 growable_array_length_field_name); 2370 growable_array_length_field_name);
2370 intptr_t array_offset = GetFieldOffset(growable_array_class, 2371 intptr_t array_offset = GetFieldOffset(growable_array_class,
2371 growable_array_array_field_name); 2372 growable_array_array_field_name);
2372 VisitLoadTwo(node->array(), node->index_expr(), EDX, EAX); 2373 VisitLoadTwo(node->array(), node->index_expr(), EDX, EAX);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2411 const Class& object_array_class = 2412 const Class& object_array_class =
2412 Class::ZoneHandle(object_store->array_class()); 2413 Class::ZoneHandle(object_store->array_class());
2413 const ICData& ic_data = node->ICDataAtId(node->id()); 2414 const ICData& ic_data = node->ICDataAtId(node->id());
2414 if (ic_data.NumberOfChecks() == 0) { 2415 if (ic_data.NumberOfChecks() == 0) {
2415 VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX); 2416 VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX);
2416 DeoptimizationBlob* deopt_blob = 2417 DeoptimizationBlob* deopt_blob =
2417 AddDeoptimizationBlob(node, EBX, ECX, kDeoptNoTypeFeedback); 2418 AddDeoptimizationBlob(node, EBX, ECX, kDeoptNoTypeFeedback);
2418 __ jmp(deopt_blob->label()); 2419 __ jmp(deopt_blob->label());
2419 return; 2420 return;
2420 } 2421 }
2422
2421 if (AtIdNodeHasOnlyClass(node, node->id(), object_array_class)) { 2423 if (AtIdNodeHasOnlyClass(node, node->id(), object_array_class)) {
2422 VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX); 2424 VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX);
2423 DeoptimizationBlob* deopt_blob = 2425 DeoptimizationBlob* deopt_blob =
2424 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed); 2426 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed);
2425 __ popl(EAX); // array. 2427 __ popl(EAX); // array.
2426 // ECX: value, EBX:index, EAX: array. 2428 // ECX: value, EBX:index, EAX: array.
2427 // Check type of array. 2429 // Check class of array.
2428 __ testl(EAX, Immediate(kSmiTagMask)); 2430 __ testl(EAX, Immediate(kSmiTagMask));
2429 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt. 2431 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt.
2430 __ movl(EDX, FieldAddress(EAX, Object::class_offset())); 2432 __ movl(EDX, FieldAddress(EAX, Object::class_offset()));
2431 __ CompareObject(EDX, object_array_class); 2433 __ CompareObject(EDX, object_array_class);
2432 __ j(NOT_EQUAL, deopt_blob->label()); // Not ObjectArray -> deopt. 2434 __ j(NOT_EQUAL, deopt_blob->label()); // Not ObjectArray -> deopt.
2433 // Check type of index. 2435 // Check class of index.
2434 __ testl(EBX, Immediate(kSmiTagMask)); 2436 __ testl(EBX, Immediate(kSmiTagMask));
2435 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt. 2437 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
2436 // Range check. 2438 // Range check.
2437 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); 2439 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset()));
2438 __ j(ABOVE_EQUAL, deopt_blob->label()); // Range error -> deopt. 2440 __ j(ABOVE_EQUAL, deopt_blob->label()); // Range error -> deopt.
2439 ASSERT(kSmiTagShift == 1); 2441 ASSERT(kSmiTagShift == 1);
2440 __ StoreIntoObject(EAX, 2442 __ StoreIntoObject(EAX,
2441 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), 2443 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)),
2442 ECX); 2444 ECX);
2443 if (CodeGenerator::IsResultNeeded(node)) { 2445 if (CodeGenerator::IsResultNeeded(node)) {
2444 __ pushl(ECX); 2446 __ pushl(ECX);
2445 } 2447 }
2446 return; 2448 return;
2447 } 2449 }
2450
2451 const String& growable_object_array_class_name = String::Handle(
2452 String::NewSymbol(kGrowableArrayClassName));
2453 const Class& growable_array_class = Class::ZoneHandle(
2454 Library::Handle(Library::CoreImplLibrary()).
2455 LookupClass(growable_object_array_class_name));
2456 ASSERT(!growable_array_class.IsNull());
2457 if (AtIdNodeHasOnlyClass(node, node->id(), growable_array_class)) {
2458 const String& growable_array_length_field_name =
2459 String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName));
2460 const String& growable_array_array_field_name =
2461 String::Handle(String::NewSymbol(kGrowableArrayArrayFieldName));
2462 intptr_t length_offset = GetFieldOffset(growable_array_class,
2463 growable_array_length_field_name);
2464 intptr_t array_offset = GetFieldOffset(growable_array_class,
2465 growable_array_array_field_name);
2466 VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX);
2467 DeoptimizationBlob* deopt_blob =
2468 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed);
2469 __ popl(EAX); // Array.
2470 // ECX: value, EBX:index, EAX: array, EDX: scratch.
2471 // Check class of array.
2472 __ testl(EAX, Immediate(kSmiTagMask));
2473 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt.
2474 __ movl(EDX, FieldAddress(EAX, Object::class_offset()));
2475 __ CompareObject(EDX, growable_array_class);
2476 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray -> deopt.
2477 // Check class of index.
2478 __ testl(EBX, Immediate(kSmiTagMask));
2479 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
2480 // Range check: deoptimize if out of bounds.
2481 __ cmpl(EBX, FieldAddress(EAX, length_offset));
2482 __ j(ABOVE_EQUAL, deopt_blob->label());
2483 __ movl(EDX, FieldAddress(EAX, array_offset)); // backingArray.
2484 // Note that EAX is Smi, i.e, times 2.
2485 ASSERT(kSmiTagShift == 1);
2486 __ StoreIntoObject(EDX,
2487 FieldAddress(EDX, EBX, TIMES_2, sizeof(RawArray)),
2488 ECX);
2489 if (CodeGenerator::IsResultNeeded(node)) {
2490 __ pushl(ECX);
2491 }
2492 return;
2493 }
2448 node->index_expr()->Visit(this); 2494 node->index_expr()->Visit(this);
2449 node->value()->Visit(this); 2495 node->value()->Visit(this);
2450 GenerateStoreIndexed(node->id(), node->token_index(), IsResultNeeded(node)); 2496 GenerateStoreIndexed(node->id(), node->token_index(), IsResultNeeded(node));
2451 } 2497 }
2452 2498
2453 2499
2454 void OptimizingCodeGenerator::VisitForNode(ForNode* node) { 2500 void OptimizingCodeGenerator::VisitForNode(ForNode* node) {
2455 if (FLAG_enable_type_checks) { 2501 if (FLAG_enable_type_checks) {
2456 CodeGenerator::VisitForNode(node); 2502 CodeGenerator::VisitForNode(node);
2457 return; 2503 return;
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
3001 } 3047 }
3002 } 3048 }
3003 // TODO(srdjan): Implement unary kSUB (negate) Mint. 3049 // TODO(srdjan): Implement unary kSUB (negate) Mint.
3004 CodeGenerator::VisitUnaryOpNode(node); 3050 CodeGenerator::VisitUnaryOpNode(node);
3005 } 3051 }
3006 3052
3007 3053
3008 } // namespace dart 3054 } // namespace dart
3009 3055
3010 #endif // defined TARGET_ARCH_IA32 3056 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_ia32.cc ('k') | tests/language/src/OptimizationTest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698