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

Side by Side Diff: vm/opt_code_generator_ia32.cc

Issue 10012042: Wire GrowableArray to use the internal VM object. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 8 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) 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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 } 230 }
231 231
232 private: 232 private:
233 GrowableArray<const Class*> classes_; 233 GrowableArray<const Class*> classes_;
234 GrowableArray<const LocalVariable*> locals_; 234 GrowableArray<const LocalVariable*> locals_;
235 235
236 DISALLOW_COPY_AND_ASSIGN(ClassesForLocals); 236 DISALLOW_COPY_AND_ASSIGN(ClassesForLocals);
237 }; 237 };
238 238
239 239
240 static const char* kGrowableArrayClassName = "GrowableObjectArray";
241 static const char* kGrowableArrayLengthFieldName = "_length";
242 static const char* kGrowableArrayArrayFieldName = "backingArray";
243
244
245 OptimizingCodeGenerator::OptimizingCodeGenerator( 240 OptimizingCodeGenerator::OptimizingCodeGenerator(
246 Assembler* assembler, const ParsedFunction& parsed_function) 241 Assembler* assembler, const ParsedFunction& parsed_function)
247 : CodeGenerator(assembler, parsed_function), 242 : CodeGenerator(assembler, parsed_function),
248 deoptimization_blobs_(4), 243 deoptimization_blobs_(4),
249 classes_for_locals_(new ClassesForLocals()), 244 classes_for_locals_(new ClassesForLocals()),
250 smi_class_(Class::ZoneHandle(Isolate::Current()->object_store() 245 smi_class_(Class::ZoneHandle(Isolate::Current()->object_store()
251 ->smi_class())), 246 ->smi_class())),
252 double_class_(Class::ZoneHandle(Isolate::Current()->object_store() 247 double_class_(Class::ZoneHandle(Isolate::Current()->object_store()
253 ->double_class())) { 248 ->double_class())),
249 growable_object_array_class_(Class::ZoneHandle(Isolate::Current()
250 ->object_store()->growable_object_array_class())) {
254 ASSERT(parsed_function.function().is_optimizable()); 251 ASSERT(parsed_function.function().is_optimizable());
255 } 252 }
256 253
257 254
258 DeoptimizationBlob* 255 DeoptimizationBlob*
259 OptimizingCodeGenerator::AddDeoptimizationBlob(AstNode* node, 256 OptimizingCodeGenerator::AddDeoptimizationBlob(AstNode* node,
260 DeoptReasonId reason_id) { 257 DeoptReasonId reason_id) {
261 DeoptimizationBlob* d = new DeoptimizationBlob(node, reason_id); 258 DeoptimizationBlob* d = new DeoptimizationBlob(node, reason_id);
262 deoptimization_blobs_.Add(d); 259 deoptimization_blobs_.Add(d);
263 return d; 260 return d;
(...skipping 1353 matching lines...) Expand 10 before | Expand all | Expand 10 after
1617 1614
1618 Recognizer::Kind recognized_kind = Recognizer::RecognizeKind(target); 1615 Recognizer::Kind recognized_kind = Recognizer::RecognizeKind(target);
1619 switch (recognized_kind) { 1616 switch (recognized_kind) {
1620 case Recognizer::kObjectArrayLength: { 1617 case Recognizer::kObjectArrayLength: {
1621 TraceOpt(node, "Inlines ObjectArray.length"); 1618 TraceOpt(node, "Inlines ObjectArray.length");
1622 __ movl(EAX, FieldAddress(EBX, Array::length_offset())); 1619 __ movl(EAX, FieldAddress(EBX, Array::length_offset()));
1623 return; 1620 return;
1624 } 1621 }
1625 case Recognizer::kGrowableArrayLength: { 1622 case Recognizer::kGrowableArrayLength: {
1626 TraceOpt(node, "Inlines GrowableObjectArray.length"); 1623 TraceOpt(node, "Inlines GrowableObjectArray.length");
1627 intptr_t field_offset = GetFieldOffset( 1624 __ movl(EAX, FieldAddress(EBX, GrowableObjectArray::length_offset()));
1628 cls,
1629 String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName)));
1630 __ movl(EAX, FieldAddress(EBX, field_offset));
1631 return; 1625 return;
1632 } 1626 }
1633 case Recognizer::kStringBaseLength: { 1627 case Recognizer::kStringBaseLength: {
1634 TraceOpt(node, "Inlines StringBase.length"); 1628 TraceOpt(node, "Inlines StringBase.length");
1635 __ movl(EAX, FieldAddress(EBX, String::length_offset())); 1629 __ movl(EAX, FieldAddress(EBX, String::length_offset()));
1636 return; 1630 return;
1637 } 1631 }
1638 default: 1632 default:
1639 UNIMPLEMENTED(); 1633 UNIMPLEMENTED();
1640 } 1634 }
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
2368 __ cmpl(EDX, FieldAddress(EBX, Array::length_offset())); 2362 __ cmpl(EDX, FieldAddress(EBX, Array::length_offset()));
2369 __ j(ABOVE_EQUAL, deopt_blob->label()); 2363 __ j(ABOVE_EQUAL, deopt_blob->label());
2370 // Note that EDX is Smi, i.e, times 2. 2364 // Note that EDX is Smi, i.e, times 2.
2371 ASSERT(kSmiTagShift == 1); 2365 ASSERT(kSmiTagShift == 1);
2372 __ movl(EAX, FieldAddress(EBX, EDX, TIMES_2, sizeof(RawArray))); 2366 __ movl(EAX, FieldAddress(EBX, EDX, TIMES_2, sizeof(RawArray)));
2373 HandleResult(node, EAX); 2367 HandleResult(node, EAX);
2374 TraceOpt(node, kMessage); 2368 TraceOpt(node, kMessage);
2375 return; 2369 return;
2376 } 2370 }
2377 2371
2378 const String& growable_object_array_class_name = String::Handle( 2372 if (AtIdNodeHasClassAt(node, node->id(), growable_object_array_class_, 0)) {
2379 String::NewSymbol(kGrowableArrayClassName));
2380 const Class& growable_array_class = Class::ZoneHandle(
2381 Library::Handle(Library::CoreImplLibrary()).
2382 LookupClass(growable_object_array_class_name));
2383 ASSERT(!growable_array_class.IsNull());
2384 if (AtIdNodeHasClassAt(node, node->id(), growable_array_class, 0)) {
2385 const String& growable_array_length_field_name =
2386 String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName));
2387 const String& growable_array_array_field_name =
2388 String::Handle(String::NewSymbol(kGrowableArrayArrayFieldName));
2389 intptr_t length_offset = GetFieldOffset(growable_array_class,
2390 growable_array_length_field_name);
2391 intptr_t array_offset = GetFieldOffset(growable_array_class,
2392 growable_array_array_field_name);
2393 CodeGenInfo array_info(node->array()); 2373 CodeGenInfo array_info(node->array());
2394 CodeGenInfo index_info(node->index_expr()); 2374 CodeGenInfo index_info(node->index_expr());
2395 VisitLoadTwo(node->array(), node->index_expr(), EDX, EAX); 2375 VisitLoadTwo(node->array(), node->index_expr(), EDX, EAX);
2396 DeoptimizationBlob* deopt_blob = 2376 DeoptimizationBlob* deopt_blob =
2397 AddDeoptimizationBlob(node, EDX, EAX, kDeoptLoadIndexedGrowableArray); 2377 AddDeoptimizationBlob(node, EDX, EAX, kDeoptLoadIndexedGrowableArray);
2398 // EAX: index, EDX: array. 2378 // EAX: index, EDX: array.
2399 if (!index_info.IsClass(smi_class_)) { 2379 if (!index_info.IsClass(smi_class_)) {
2400 __ testl(EAX, Immediate(kSmiTagMask)); 2380 __ testl(EAX, Immediate(kSmiTagMask));
2401 __ j(NOT_ZERO, deopt_blob->label()); // Not Smi index. 2381 __ j(NOT_ZERO, deopt_blob->label()); // Not Smi index.
2402 PropagateBackLocalClass(node->index_expr(), smi_class_); 2382 PropagateBackLocalClass(node->index_expr(), smi_class_);
2403 } 2383 }
2404 if (!array_info.IsClass(growable_array_class)) { 2384 if (!array_info.IsClass(growable_object_array_class_)) {
2405 __ testl(EDX, Immediate(kSmiTagMask)); 2385 __ testl(EDX, Immediate(kSmiTagMask));
2406 __ j(ZERO, deopt_blob->label()); // Array is Smi. 2386 __ j(ZERO, deopt_blob->label()); // Array is Smi.
2407 __ movl(EBX, FieldAddress(EDX, Object::class_offset())); 2387 __ movl(EBX, FieldAddress(EDX, Object::class_offset()));
2408 __ CompareObject(EBX, growable_array_class); 2388 __ CompareObject(EBX, growable_object_array_class_);
2409 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray. 2389 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray.
2410 PropagateBackLocalClass(node->array(), growable_array_class); 2390 PropagateBackLocalClass(node->array(), growable_object_array_class_);
2411 } 2391 }
2412 // Range check: deoptimize if out of bounds. 2392 // Range check: deoptimize if out of bounds.
2413 __ cmpl(EAX, FieldAddress(EDX, length_offset)); 2393 __ cmpl(EAX, FieldAddress(EDX, GrowableObjectArray::length_offset()));
2414 __ j(ABOVE_EQUAL, deopt_blob->label()); 2394 __ j(ABOVE_EQUAL, deopt_blob->label());
2415 __ movl(EDX, FieldAddress(EDX, array_offset)); // backingArray. 2395 __ movl(EDX, FieldAddress(EDX, GrowableObjectArray::data_offset()));
2416 // Note that EAX is Smi, i.e, times 2. 2396 // Note that EAX is Smi, i.e, times 2.
2417 ASSERT(kSmiTagShift == 1); 2397 ASSERT(kSmiTagShift == 1);
2418 __ movl(EAX, FieldAddress(EDX, EAX, TIMES_2, sizeof(RawArray))); 2398 __ movl(EAX, FieldAddress(EDX, EAX, TIMES_2, sizeof(RawArray)));
2419 HandleResult(node, EAX); 2399 HandleResult(node, EAX);
2420 return; 2400 return;
2421 } else { 2401 } else {
2422 // E.g., HashMap. 2402 // E.g., HashMap.
2423 TraceNotOpt(node, kMessage); 2403 TraceNotOpt(node, kMessage);
2424 } 2404 }
2425 CodeGenerator::VisitLoadIndexedNode(node); 2405 CodeGenerator::VisitLoadIndexedNode(node);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2487 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); 2467 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset()));
2488 __ j(ABOVE_EQUAL, deopt_blob->label()); // Range error -> deopt. 2468 __ j(ABOVE_EQUAL, deopt_blob->label()); // Range error -> deopt.
2489 ASSERT(kSmiTagShift == 1); 2469 ASSERT(kSmiTagShift == 1);
2490 __ StoreIntoObject(EAX, 2470 __ StoreIntoObject(EAX,
2491 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), 2471 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)),
2492 ECX); 2472 ECX);
2493 HandleResult(node, ECX); 2473 HandleResult(node, ECX);
2494 return; 2474 return;
2495 } 2475 }
2496 2476
2497 const String& growable_object_array_class_name = String::Handle( 2477 if (AtIdNodeHasClassAt(node, node->id(), growable_object_array_class_, 0)) {
2498 String::NewSymbol(kGrowableArrayClassName));
2499 const Class& growable_array_class = Class::ZoneHandle(
2500 Library::Handle(Library::CoreImplLibrary()).
2501 LookupClass(growable_object_array_class_name));
2502 ASSERT(!growable_array_class.IsNull());
2503 if (AtIdNodeHasClassAt(node, node->id(), growable_array_class, 0)) {
2504 const String& growable_array_length_field_name =
2505 String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName));
2506 const String& growable_array_array_field_name =
2507 String::Handle(String::NewSymbol(kGrowableArrayArrayFieldName));
2508 intptr_t length_offset = GetFieldOffset(growable_array_class,
2509 growable_array_length_field_name);
2510 intptr_t array_offset = GetFieldOffset(growable_array_class,
2511 growable_array_array_field_name);
2512 bool index_is_smi = false; 2478 bool index_is_smi = false;
2513 // Release CodeGenInfo of index quickly as it may be used in the value, 2479 // Release CodeGenInfo of index quickly as it may be used in the value,
2514 // e.g. a[i] += 3. Fixes issue 1570. 2480 // e.g. a[i] += 3. Fixes issue 1570.
2515 { 2481 {
2516 CodeGenInfo index_info(node->index_expr()); 2482 CodeGenInfo index_info(node->index_expr());
2517 node->index_expr()->Visit(this); 2483 node->index_expr()->Visit(this);
2518 index_is_smi = index_info.IsClass(smi_class_); 2484 index_is_smi = index_info.IsClass(smi_class_);
2519 } 2485 }
2520 VisitLoadOne(node->value(), ECX); 2486 VisitLoadOne(node->value(), ECX);
2521 DeoptimizationBlob* deopt_blob = 2487 DeoptimizationBlob* deopt_blob =
2522 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed); 2488 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed);
2523 __ popl(EBX); // index. 2489 __ popl(EBX); // index.
2524 __ popl(EAX); // array. 2490 __ popl(EAX); // array.
2525 // ECX: value, EBX:index, EAX: array, EDX: scratch. 2491 // ECX: value, EBX:index, EAX: array, EDX: scratch.
2526 // Check class of array. 2492 // Check class of array.
2527 if (class_of_this_array.raw() != growable_array_class.raw()) { 2493 if (class_of_this_array.raw() != growable_object_array_class_.raw()) {
2528 __ testl(EAX, Immediate(kSmiTagMask)); 2494 __ testl(EAX, Immediate(kSmiTagMask));
2529 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt. 2495 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt.
2530 __ movl(EDX, FieldAddress(EAX, Object::class_offset())); 2496 __ movl(EDX, FieldAddress(EAX, Object::class_offset()));
2531 __ CompareObject(EDX, growable_array_class); 2497 __ CompareObject(EDX, growable_object_array_class_);
2532 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray. 2498 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray.
2533 PropagateBackLocalClass(node->array(), growable_array_class); 2499 PropagateBackLocalClass(node->array(), growable_object_array_class_);
2534 } 2500 }
2535 // Check class of index. 2501 // Check class of index.
2536 if (!index_is_smi) { 2502 if (!index_is_smi) {
2537 __ testl(EBX, Immediate(kSmiTagMask)); 2503 __ testl(EBX, Immediate(kSmiTagMask));
2538 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt. 2504 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
2539 PropagateBackLocalClass(node->index_expr(), smi_class_); 2505 PropagateBackLocalClass(node->index_expr(), smi_class_);
2540 } 2506 }
2541 // Range check: deoptimize if out of bounds. 2507 // Range check: deoptimize if out of bounds.
2542 __ cmpl(EBX, FieldAddress(EAX, length_offset)); 2508 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
2543 __ j(ABOVE_EQUAL, deopt_blob->label()); 2509 __ j(ABOVE_EQUAL, deopt_blob->label());
2544 __ movl(EDX, FieldAddress(EAX, array_offset)); // backingArray. 2510 __ movl(EDX, FieldAddress(EAX, GrowableObjectArray::data_offset()));
2545 // Note that EAX is Smi, i.e, times 2. 2511 // Note that EAX is Smi, i.e, times 2.
2546 ASSERT(kSmiTagShift == 1); 2512 ASSERT(kSmiTagShift == 1);
2547 __ StoreIntoObject(EDX, 2513 __ StoreIntoObject(EDX,
2548 FieldAddress(EDX, EBX, TIMES_2, sizeof(RawArray)), 2514 FieldAddress(EDX, EBX, TIMES_2, sizeof(RawArray)),
2549 ECX); 2515 ECX);
2550 HandleResult(node, ECX); 2516 HandleResult(node, ECX);
2551 return; 2517 return;
2552 } 2518 }
2553 node->index_expr()->Visit(this); 2519 node->index_expr()->Visit(this);
2554 node->value()->Visit(this); 2520 node->value()->Visit(this);
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
3100 } 3066 }
3101 } 3067 }
3102 // TODO(srdjan): Implement unary kSUB (negate) Mint. 3068 // TODO(srdjan): Implement unary kSUB (negate) Mint.
3103 CodeGenerator::VisitUnaryOpNode(node); 3069 CodeGenerator::VisitUnaryOpNode(node);
3104 } 3070 }
3105 3071
3106 3072
3107 } // namespace dart 3073 } // namespace dart
3108 3074
3109 #endif // defined TARGET_ARCH_IA32 3075 #endif // defined TARGET_ARCH_IA32
OLDNEW
« vm/object.cc ('K') | « vm/opt_code_generator_ia32.h ('k') | vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698