| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |