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

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

Issue 836593002: Deletion barrier: Distinguish+verify field initialization in ia32 generated code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 11 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 | « runtime/vm/scavenger.cc ('k') | no next file » | 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) 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/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 __ pushl(EAX); // Array is in EAX and on top of stack. 362 __ pushl(EAX); // Array is in EAX and on top of stack.
363 __ leal(EBX, Address(EBP, EDX, TIMES_4, kParamEndSlotFromFp * kWordSize)); 363 __ leal(EBX, Address(EBP, EDX, TIMES_4, kParamEndSlotFromFp * kWordSize));
364 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); 364 __ leal(ECX, FieldAddress(EAX, Array::data_offset()));
365 // EBX: address of first argument on stack. 365 // EBX: address of first argument on stack.
366 // ECX: address of first argument in array. 366 // ECX: address of first argument in array.
367 Label loop, loop_condition; 367 Label loop, loop_condition;
368 __ jmp(&loop_condition, Assembler::kNearJump); 368 __ jmp(&loop_condition, Assembler::kNearJump);
369 __ Bind(&loop); 369 __ Bind(&loop);
370 __ movl(EDI, Address(EBX, 0)); 370 __ movl(EDI, Address(EBX, 0));
371 // No generational barrier needed, since array is in new space. 371 // No generational barrier needed, since array is in new space.
372 __ StoreIntoObjectNoBarrier(EAX, Address(ECX, 0), EDI); 372 __ InitializeFieldNoBarrier(EAX, Address(ECX, 0), EDI);
373 __ AddImmediate(ECX, Immediate(kWordSize)); 373 __ AddImmediate(ECX, Immediate(kWordSize));
374 __ AddImmediate(EBX, Immediate(-kWordSize)); 374 __ AddImmediate(EBX, Immediate(-kWordSize));
375 __ Bind(&loop_condition); 375 __ Bind(&loop_condition);
376 __ decl(EDX); 376 __ decl(EDX);
377 __ j(POSITIVE, &loop, Assembler::kNearJump); 377 __ j(POSITIVE, &loop, Assembler::kNearJump);
378 } 378 }
379 379
380 380
381 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 381 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
382 intptr_t deopt_reason, 382 intptr_t deopt_reason,
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 624
625 // Get the class index and insert it into the tags. 625 // Get the class index and insert it into the tags.
626 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cid))); 626 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cid)));
627 __ movl(FieldAddress(EAX, Array::tags_offset()), EDI); // Tags. 627 __ movl(FieldAddress(EAX, Array::tags_offset()), EDI); // Tags.
628 } 628 }
629 // EAX: new object start as a tagged pointer. 629 // EAX: new object start as a tagged pointer.
630 // EBX: new object end address. 630 // EBX: new object end address.
631 // ECX: array element type. 631 // ECX: array element type.
632 // EDX: Array length as Smi (preserved). 632 // EDX: Array length as Smi (preserved).
633 // Store the type argument field. 633 // Store the type argument field.
634 __ StoreIntoObjectNoBarrier(EAX, 634 __ InitializeFieldNoBarrier(EAX,
635 FieldAddress(EAX, Array::type_arguments_offset()), 635 FieldAddress(EAX, Array::type_arguments_offset()),
636 ECX); 636 ECX);
637 637
638 // Set the length field. 638 // Set the length field.
639 __ StoreIntoObjectNoBarrier(EAX, 639 __ InitializeFieldNoBarrier(EAX,
640 FieldAddress(EAX, Array::length_offset()), 640 FieldAddress(EAX, Array::length_offset()),
641 EDX); 641 EDX);
642 642
643 // Initialize all array elements to raw_null. 643 // Initialize all array elements to raw_null.
644 // EAX: new object start as a tagged pointer. 644 // EAX: new object start as a tagged pointer.
645 // EBX: new object end address. 645 // EBX: new object end address.
646 // EDI: iterator which initially points to the start of the variable 646 // EDI: iterator which initially points to the start of the variable
647 // data area to be initialized. 647 // data area to be initialized.
648 // ECX: array element type. 648 // ECX: array element type.
649 // EDX: array length as Smi. 649 // EDX: array length as Smi.
650 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray))); 650 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray)));
651 Label done; 651 Label done;
652 Label init_loop; 652 Label init_loop;
653 __ Bind(&init_loop); 653 __ Bind(&init_loop);
654 __ cmpl(EDI, EBX); 654 __ cmpl(EDI, EBX);
655 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); 655 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
656 // No generational barrier needed, since we are storing null. 656 // No generational barrier needed, since we are storing null.
657 __ StoreIntoObjectNoBarrier(EAX, Address(EDI, 0), Object::null_object()); 657 __ InitializeFieldNoBarrier(EAX, Address(EDI, 0), Object::null_object());
658 __ addl(EDI, Immediate(kWordSize)); 658 __ addl(EDI, Immediate(kWordSize));
659 __ jmp(&init_loop, Assembler::kNearJump); 659 __ jmp(&init_loop, Assembler::kNearJump);
660 __ Bind(&done); 660 __ Bind(&done);
661 __ ret(); // returns the newly allocated object in EAX. 661 __ ret(); // returns the newly allocated object in EAX.
662 662
663 // Unable to allocate the array using the fast inline code, just call 663 // Unable to allocate the array using the fast inline code, just call
664 // into the runtime. 664 // into the runtime.
665 __ Bind(&slow_case); 665 __ Bind(&slow_case);
666 // Create a stub frame as we are pushing some objects on the stack before 666 // Create a stub frame as we are pushing some objects on the stack before
667 // calling into the runtime. 667 // calling into the runtime.
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 __ movl(EAX, Address::Absolute(heap->TopAddress(space))); 806 __ movl(EAX, Address::Absolute(heap->TopAddress(space)));
807 __ addl(EBX, EAX); 807 __ addl(EBX, EAX);
808 // Check if the allocation fits into the remaining space. 808 // Check if the allocation fits into the remaining space.
809 // EAX: potential new object. 809 // EAX: potential new object.
810 // EBX: potential next object start. 810 // EBX: potential next object start.
811 // EDX: number of context variables. 811 // EDX: number of context variables.
812 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); 812 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space)));
813 if (FLAG_use_slow_path) { 813 if (FLAG_use_slow_path) {
814 __ jmp(&slow_case); 814 __ jmp(&slow_case);
815 } else { 815 } else {
816 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); 816 #if defined(DEBUG)
817 static const bool kJumpLength = Assembler::kFarJump;
818 #else
819 static const bool kJumpLength = Assembler::kNearJump;
820 #endif // DEBUG
821 __ j(ABOVE_EQUAL, &slow_case, kJumpLength);
817 } 822 }
818 823
819 // Successfully allocated the object, now update top to point to 824 // Successfully allocated the object, now update top to point to
820 // next object start and initialize the object. 825 // next object start and initialize the object.
821 // EAX: new object. 826 // EAX: new object.
822 // EBX: next object start. 827 // EBX: next object start.
823 // EDX: number of context variables. 828 // EDX: number of context variables.
824 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); 829 __ movl(Address::Absolute(heap->TopAddress(space)), EBX);
825 __ addl(EAX, Immediate(kHeapObjectTag)); 830 __ addl(EAX, Immediate(kHeapObjectTag));
826 // EBX: Size of allocation in bytes. 831 // EBX: Size of allocation in bytes.
(...skipping 27 matching lines...) Expand all
854 859
855 // Setup up number of context variables field. 860 // Setup up number of context variables field.
856 // EAX: new object. 861 // EAX: new object.
857 // EDX: number of context variables as integer value (not object). 862 // EDX: number of context variables as integer value (not object).
858 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); 863 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX);
859 864
860 // Setup the parent field. 865 // Setup the parent field.
861 // EAX: new object. 866 // EAX: new object.
862 // EDX: number of context variables. 867 // EDX: number of context variables.
863 // No generational barrier needed, since we are storing null. 868 // No generational barrier needed, since we are storing null.
864 __ StoreIntoObjectNoBarrier(EAX, 869 __ InitializeFieldNoBarrier(EAX,
865 FieldAddress(EAX, Context::parent_offset()), 870 FieldAddress(EAX, Context::parent_offset()),
866 Object::null_object()); 871 Object::null_object());
867 872
868 // Initialize the context variables. 873 // Initialize the context variables.
869 // EAX: new object. 874 // EAX: new object.
870 // EDX: number of context variables. 875 // EDX: number of context variables.
871 { 876 {
872 Label loop, entry; 877 Label loop, entry;
873 __ leal(EBX, FieldAddress(EAX, Context::variable_offset(0))); 878 __ leal(EBX, FieldAddress(EAX, Context::variable_offset(0)));
874 879
875 __ jmp(&entry, Assembler::kNearJump); 880 __ jmp(&entry, Assembler::kNearJump);
876 __ Bind(&loop); 881 __ Bind(&loop);
877 __ decl(EDX); 882 __ decl(EDX);
878 // No generational barrier needed, since we are storing null. 883 // No generational barrier needed, since we are storing null.
879 __ StoreIntoObjectNoBarrier(EAX, 884 __ InitializeFieldNoBarrier(EAX,
880 Address(EBX, EDX, TIMES_4, 0), 885 Address(EBX, EDX, TIMES_4, 0),
881 Object::null_object()); 886 Object::null_object());
882 __ Bind(&entry); 887 __ Bind(&entry);
883 __ cmpl(EDX, Immediate(0)); 888 __ cmpl(EDX, Immediate(0));
884 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 889 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
885 } 890 }
886 891
887 // Done allocating and initializing the context. 892 // Done allocating and initializing the context.
888 // EAX: new object. 893 // EAX: new object.
889 __ ret(); 894 __ ret();
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 // EAX: new object (tagged). 1052 // EAX: new object (tagged).
1048 // EBX: next object start. 1053 // EBX: next object start.
1049 // EDX: new object type arguments (if is_cls_parameterized). 1054 // EDX: new object type arguments (if is_cls_parameterized).
1050 // First try inlining the initialization without a loop. 1055 // First try inlining the initialization without a loop.
1051 if (instance_size < (kInlineInstanceSize * kWordSize)) { 1056 if (instance_size < (kInlineInstanceSize * kWordSize)) {
1052 // Check if the object contains any non-header fields. 1057 // Check if the object contains any non-header fields.
1053 // Small objects are initialized using a consecutive set of writes. 1058 // Small objects are initialized using a consecutive set of writes.
1054 for (intptr_t current_offset = Instance::NextFieldOffset(); 1059 for (intptr_t current_offset = Instance::NextFieldOffset();
1055 current_offset < instance_size; 1060 current_offset < instance_size;
1056 current_offset += kWordSize) { 1061 current_offset += kWordSize) {
1057 __ StoreIntoObjectNoBarrier(EAX, 1062 __ InitializeFieldNoBarrier(EAX,
1058 FieldAddress(EAX, current_offset), 1063 FieldAddress(EAX, current_offset),
1059 Object::null_object()); 1064 Object::null_object());
1060 } 1065 }
1061 } else { 1066 } else {
1062 __ leal(ECX, FieldAddress(EAX, Instance::NextFieldOffset())); 1067 __ leal(ECX, FieldAddress(EAX, Instance::NextFieldOffset()));
1063 // Loop until the whole object is initialized. 1068 // Loop until the whole object is initialized.
1064 // EAX: new object (tagged). 1069 // EAX: new object (tagged).
1065 // EBX: next object start. 1070 // EBX: next object start.
1066 // ECX: next word to be initialized. 1071 // ECX: next word to be initialized.
1067 // EDX: new object type arguments (if is_cls_parameterized). 1072 // EDX: new object type arguments (if is_cls_parameterized).
1068 Label init_loop; 1073 Label init_loop;
1069 Label done; 1074 Label done;
1070 __ Bind(&init_loop); 1075 __ Bind(&init_loop);
1071 __ cmpl(ECX, EBX); 1076 __ cmpl(ECX, EBX);
1072 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); 1077 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
1073 __ StoreIntoObjectNoBarrier(EAX, 1078 __ InitializeFieldNoBarrier(EAX,
1074 Address(ECX, 0), 1079 Address(ECX, 0),
1075 Object::null_object()); 1080 Object::null_object());
1076 __ addl(ECX, Immediate(kWordSize)); 1081 __ addl(ECX, Immediate(kWordSize));
1077 __ jmp(&init_loop, Assembler::kNearJump); 1082 __ jmp(&init_loop, Assembler::kNearJump);
1078 __ Bind(&done); 1083 __ Bind(&done);
1079 } 1084 }
1080 if (is_cls_parameterized) { 1085 if (is_cls_parameterized) {
1081 // EDX: new object type arguments. 1086 // EDX: new object type arguments.
1082 // Set the type arguments in the new object. 1087 // Set the type arguments in the new object.
1083 intptr_t offset = cls.type_arguments_field_offset(); 1088 intptr_t offset = cls.type_arguments_field_offset();
1084 __ StoreIntoObjectNoBarrier(EAX, FieldAddress(EAX, offset), EDX); 1089 // TODO(koda): Figure out why previous content is sometimes null here.
1090 __ InitializeFieldNoBarrier(EAX, FieldAddress(EAX, offset), EDX);
1085 } 1091 }
1086 // Done allocating and initializing the instance. 1092 // Done allocating and initializing the instance.
1087 // EAX: new object (tagged). 1093 // EAX: new object (tagged).
1088 __ ret(); 1094 __ ret();
1089 1095
1090 __ Bind(&slow_case); 1096 __ Bind(&slow_case);
1091 } 1097 }
1092 // If is_cls_parameterized: 1098 // If is_cls_parameterized:
1093 // EDX: new object type arguments. 1099 // EDX: new object type arguments.
1094 // Create a stub frame as we are pushing some objects on the stack before 1100 // Create a stub frame as we are pushing some objects on the stack before
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after
2039 const Register temp = ECX; 2045 const Register temp = ECX;
2040 __ movl(left, Address(ESP, 2 * kWordSize)); 2046 __ movl(left, Address(ESP, 2 * kWordSize));
2041 __ movl(right, Address(ESP, 1 * kWordSize)); 2047 __ movl(right, Address(ESP, 1 * kWordSize));
2042 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2048 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2043 __ ret(); 2049 __ ret();
2044 } 2050 }
2045 2051
2046 } // namespace dart 2052 } // namespace dart
2047 2053
2048 #endif // defined TARGET_ARCH_IA32 2054 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/scavenger.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698