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

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

Issue 685003002: Add missing StoreIntoObject calls in generated code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 1 month 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') | 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 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 338 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
339 __ LeaveFrame(); 339 __ LeaveFrame();
340 __ jmp(EAX); 340 __ jmp(EAX);
341 __ int3(); 341 __ int3();
342 } 342 }
343 343
344 344
345 // Input parameters: 345 // Input parameters:
346 // EDX: smi-tagged argument count, may be zero. 346 // EDX: smi-tagged argument count, may be zero.
347 // EBP[kParamEndSlotFromFp + 1]: last argument. 347 // EBP[kParamEndSlotFromFp + 1]: last argument.
348 // Uses EAX, EBX, ECX, EDX. 348 // Uses EAX, EBX, ECX, EDX, EDI.
349 static void PushArgumentsArray(Assembler* assembler) { 349 static void PushArgumentsArray(Assembler* assembler) {
350 const Immediate& raw_null = 350 const Immediate& raw_null =
351 Immediate(reinterpret_cast<intptr_t>(Object::null())); 351 Immediate(reinterpret_cast<intptr_t>(Object::null()));
352 StubCode* stub_code = Isolate::Current()->stub_code(); 352 StubCode* stub_code = Isolate::Current()->stub_code();
353 353
354 // Allocate array to store arguments of caller. 354 // Allocate array to store arguments of caller.
355 __ movl(ECX, raw_null); // Null element type for raw Array. 355 __ movl(ECX, raw_null); // Null element type for raw Array.
356 const Code& array_stub = Code::Handle(stub_code->GetAllocateArrayStub()); 356 const Code& array_stub = Code::Handle(stub_code->GetAllocateArrayStub());
357 const ExternalLabel array_label(array_stub.EntryPoint()); 357 const ExternalLabel array_label(array_stub.EntryPoint());
358 __ call(&array_label); 358 __ call(&array_label);
359 __ SmiUntag(EDX); 359 __ SmiUntag(EDX);
360 // EAX: newly allocated array. 360 // EAX: newly allocated array.
361 // EDX: length of the array (was preserved by the stub). 361 // EDX: length of the array (was preserved by the stub).
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(EAX, Address(EBX, 0)); 370 __ movl(EDI, Address(EBX, 0));
371 __ movl(Address(ECX, 0), EAX); 371 // No generational barrier needed, since array is in new space.
372 __ StoreIntoObjectNoBarrier(EAX, Address(ECX, 0), EDI);
372 __ AddImmediate(ECX, Immediate(kWordSize)); 373 __ AddImmediate(ECX, Immediate(kWordSize));
373 __ AddImmediate(EBX, Immediate(-kWordSize)); 374 __ AddImmediate(EBX, Immediate(-kWordSize));
374 __ Bind(&loop_condition); 375 __ Bind(&loop_condition);
375 __ decl(EDX); 376 __ decl(EDX);
376 __ j(POSITIVE, &loop, Assembler::kNearJump); 377 __ j(POSITIVE, &loop, Assembler::kNearJump);
377 } 378 }
378 379
379 380
380 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 381 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
381 intptr_t deopt_reason, 382 intptr_t deopt_reason,
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 // EDI: iterator which initially points to the start of the variable 646 // EDI: iterator which initially points to the start of the variable
646 // data area to be initialized. 647 // data area to be initialized.
647 // ECX: array element type. 648 // ECX: array element type.
648 // EDX: array length as Smi. 649 // EDX: array length as Smi.
649 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray))); 650 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray)));
650 Label done; 651 Label done;
651 Label init_loop; 652 Label init_loop;
652 __ Bind(&init_loop); 653 __ Bind(&init_loop);
653 __ cmpl(EDI, EBX); 654 __ cmpl(EDI, EBX);
654 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); 655 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
655 __ movl(Address(EDI, 0), raw_null); 656 // No generational barrier needed, since we are storing null.
657 __ StoreIntoObjectNoBarrier(EAX, Address(EDI, 0), Object::null_object());
656 __ addl(EDI, Immediate(kWordSize)); 658 __ addl(EDI, Immediate(kWordSize));
657 __ jmp(&init_loop, Assembler::kNearJump); 659 __ jmp(&init_loop, Assembler::kNearJump);
658 __ Bind(&done); 660 __ Bind(&done);
659 __ ret(); // returns the newly allocated object in EAX. 661 __ ret(); // returns the newly allocated object in EAX.
660 662
661 // 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
662 // into the runtime. 664 // into the runtime.
663 __ Bind(&slow_case); 665 __ Bind(&slow_case);
664 // 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
665 // calling into the runtime. 667 // calling into the runtime.
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 __ orl(EBX, 850 __ orl(EBX,
849 Immediate(RawObject::ClassIdTag::encode(cid))); 851 Immediate(RawObject::ClassIdTag::encode(cid)));
850 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags. 852 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags.
851 } 853 }
852 854
853 // Setup up number of context variables field. 855 // Setup up number of context variables field.
854 // EAX: new object. 856 // EAX: new object.
855 // EDX: number of context variables as integer value (not object). 857 // EDX: number of context variables as integer value (not object).
856 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); 858 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX);
857 859
858 const Immediate& raw_null =
859 Immediate(reinterpret_cast<intptr_t>(Object::null()));
860 // Setup the parent field. 860 // Setup the parent field.
861 // EAX: new object. 861 // EAX: new object.
862 // EDX: number of context variables. 862 // EDX: number of context variables.
863 __ movl(FieldAddress(EAX, Context::parent_offset()), raw_null); 863 // No generational barrier needed, since we are storing null.
864 __ StoreIntoObjectNoBarrier(EAX,
865 FieldAddress(EAX, Context::parent_offset()),
866 Object::null_object());
864 867
865 // Initialize the context variables. 868 // Initialize the context variables.
866 // EAX: new object. 869 // EAX: new object.
867 // EDX: number of context variables. 870 // EDX: number of context variables.
868 { 871 {
869 Label loop, entry; 872 Label loop, entry;
870 __ leal(EBX, FieldAddress(EAX, Context::variable_offset(0))); 873 __ leal(EBX, FieldAddress(EAX, Context::variable_offset(0)));
871 874
872 __ jmp(&entry, Assembler::kNearJump); 875 __ jmp(&entry, Assembler::kNearJump);
873 __ Bind(&loop); 876 __ Bind(&loop);
874 __ decl(EDX); 877 __ decl(EDX);
875 __ movl(Address(EBX, EDX, TIMES_4, 0), raw_null); 878 // No generational barrier needed, since we are storing null.
879 __ StoreIntoObjectNoBarrier(EAX,
880 Address(EBX, EDX, TIMES_4, 0),
881 Object::null_object());
876 __ Bind(&entry); 882 __ Bind(&entry);
877 __ cmpl(EDX, Immediate(0)); 883 __ cmpl(EDX, Immediate(0));
878 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 884 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
879 } 885 }
880 886
881 // Done allocating and initializing the context. 887 // Done allocating and initializing the context.
882 // EAX: new object. 888 // EAX: new object.
883 __ ret(); 889 __ ret();
884 890
885 __ Bind(&slow_case); 891 __ Bind(&slow_case);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 // EBX: potential next object start. 1024 // EBX: potential next object start.
1019 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); 1025 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space)));
1020 if (FLAG_use_slow_path) { 1026 if (FLAG_use_slow_path) {
1021 __ jmp(&slow_case); 1027 __ jmp(&slow_case);
1022 } else { 1028 } else {
1023 __ j(ABOVE_EQUAL, &slow_case); 1029 __ j(ABOVE_EQUAL, &slow_case);
1024 } 1030 }
1025 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); 1031 __ movl(Address::Absolute(heap->TopAddress(space)), EBX);
1026 __ UpdateAllocationStats(cls.id(), ECX, space); 1032 __ UpdateAllocationStats(cls.id(), ECX, space);
1027 1033
1028 // EAX: new object start. 1034 // EAX: new object start (untagged).
1029 // EBX: next object start. 1035 // EBX: next object start.
1030 // EDX: new object type arguments (if is_cls_parameterized). 1036 // EDX: new object type arguments (if is_cls_parameterized).
1031 // Set the tags. 1037 // Set the tags.
1032 uword tags = 0; 1038 uword tags = 0;
1033 tags = RawObject::SizeTag::update(instance_size, tags); 1039 tags = RawObject::SizeTag::update(instance_size, tags);
1034 ASSERT(cls.id() != kIllegalCid); 1040 ASSERT(cls.id() != kIllegalCid);
1035 tags = RawObject::ClassIdTag::update(cls.id(), tags); 1041 tags = RawObject::ClassIdTag::update(cls.id(), tags);
1036 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); 1042 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags));
1043 __ addl(EAX, Immediate(kHeapObjectTag));
1037 1044
1038 // Initialize the remaining words of the object. 1045 // Initialize the remaining words of the object.
1039 const Immediate& raw_null =
1040 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1041 1046
1042 // EAX: new object start. 1047 // EAX: new object (tagged).
1043 // EBX: next object start. 1048 // EBX: next object start.
1044 // EDX: new object type arguments (if is_cls_parameterized). 1049 // EDX: new object type arguments (if is_cls_parameterized).
1045 // First try inlining the initialization without a loop. 1050 // First try inlining the initialization without a loop.
1046 if (instance_size < (kInlineInstanceSize * kWordSize)) { 1051 if (instance_size < (kInlineInstanceSize * kWordSize)) {
1047 // Check if the object contains any non-header fields. 1052 // Check if the object contains any non-header fields.
1048 // Small objects are initialized using a consecutive set of writes. 1053 // Small objects are initialized using a consecutive set of writes.
1049 for (intptr_t current_offset = Instance::NextFieldOffset(); 1054 for (intptr_t current_offset = Instance::NextFieldOffset();
1050 current_offset < instance_size; 1055 current_offset < instance_size;
1051 current_offset += kWordSize) { 1056 current_offset += kWordSize) {
1052 __ movl(Address(EAX, current_offset), raw_null); 1057 __ StoreIntoObjectNoBarrier(EAX,
1058 FieldAddress(EAX, current_offset),
1059 Object::null_object());
1053 } 1060 }
1054 } else { 1061 } else {
1055 __ leal(ECX, Address(EAX, Instance::NextFieldOffset())); 1062 __ leal(ECX, Address(EAX, Instance::NextFieldOffset()));
1056 // Loop until the whole object is initialized. 1063 // Loop until the whole object is initialized.
1057 // EAX: new object. 1064 // EAX: new object (tagged).
1058 // EBX: next object start. 1065 // EBX: next object start.
1059 // ECX: next word to be initialized. 1066 // ECX: next word to be initialized.
1060 // EDX: new object type arguments (if is_cls_parameterized). 1067 // EDX: new object type arguments (if is_cls_parameterized).
1061 Label init_loop; 1068 Label init_loop;
1062 Label done; 1069 Label done;
1063 __ Bind(&init_loop); 1070 __ Bind(&init_loop);
1064 __ cmpl(ECX, EBX); 1071 __ cmpl(ECX, EBX);
1065 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); 1072 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
1066 __ movl(Address(ECX, 0), raw_null); 1073 __ StoreIntoObjectNoBarrier(EAX,
1074 Address(ECX, 0),
1075 Object::null_object());
1067 __ addl(ECX, Immediate(kWordSize)); 1076 __ addl(ECX, Immediate(kWordSize));
1068 __ jmp(&init_loop, Assembler::kNearJump); 1077 __ jmp(&init_loop, Assembler::kNearJump);
1069 __ Bind(&done); 1078 __ Bind(&done);
1070 } 1079 }
1071 if (is_cls_parameterized) { 1080 if (is_cls_parameterized) {
1072 // EDX: new object type arguments. 1081 // EDX: new object type arguments.
1073 // Set the type arguments in the new object. 1082 // Set the type arguments in the new object.
1074 __ movl(Address(EAX, cls.type_arguments_field_offset()), EDX); 1083 intptr_t offset = cls.type_arguments_field_offset();
1084 __ StoreIntoObjectNoBarrier(EAX, FieldAddress(EAX, offset), EDX);
1075 } 1085 }
1076 // Done allocating and initializing the instance. 1086 // Done allocating and initializing the instance.
1077 // EAX: new object. 1087 // EAX: new object (tagged).
1078 __ addl(EAX, Immediate(kHeapObjectTag));
1079 __ ret(); 1088 __ ret();
1080 1089
1081 __ Bind(&slow_case); 1090 __ Bind(&slow_case);
1082 } 1091 }
1083 // If is_cls_parameterized: 1092 // If is_cls_parameterized:
1084 // EDX: new object type arguments. 1093 // EDX: new object type arguments.
1085 // Create a stub frame as we are pushing some objects on the stack before 1094 // Create a stub frame as we are pushing some objects on the stack before
1086 // calling into the runtime. 1095 // calling into the runtime.
1087 __ EnterStubFrame(); 1096 __ EnterStubFrame();
1088 __ pushl(raw_null); // Setup space on stack for return value. 1097 __ pushl(raw_null); // Setup space on stack for return value.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1229 __ Bind(&error); 1238 __ Bind(&error);
1230 __ Stop("Incorrect IC data"); 1239 __ Stop("Incorrect IC data");
1231 __ Bind(&ok); 1240 __ Bind(&ok);
1232 #endif 1241 #endif
1233 // Update counter. 1242 // Update counter.
1234 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1243 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1235 __ movl(ECX, Address(EBX, count_offset)); 1244 __ movl(ECX, Address(EBX, count_offset));
1236 __ addl(ECX, Immediate(Smi::RawValue(1))); 1245 __ addl(ECX, Immediate(Smi::RawValue(1)));
1237 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue))); 1246 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue)));
1238 __ cmovno(EDI, ECX); 1247 __ cmovno(EDI, ECX);
1239 __ movl(Address(EBX, count_offset), EDI); 1248 __ StoreIntoSmiField(Address(EBX, count_offset), EDI);
1240 1249
1241 __ ret(); 1250 __ ret();
1242 } 1251 }
1243 1252
1244 1253
1245 // Generate inline cache check for 'num_args'. 1254 // Generate inline cache check for 'num_args'.
1246 // ECX: Inline cache data object. 1255 // ECX: Inline cache data object.
1247 // TOS(0): return address 1256 // TOS(0): return address
1248 // Control flow: 1257 // Control flow:
1249 // - If receiver is null -> jump to IC miss. 1258 // - If receiver is null -> jump to IC miss.
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 __ Bind(&found); 1386 __ Bind(&found);
1378 // EBX: Pointer to an IC data check group. 1387 // EBX: Pointer to an IC data check group.
1379 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1388 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1380 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1389 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1381 1390
1382 // Update counter. 1391 // Update counter.
1383 __ movl(EAX, Address(EBX, count_offset)); 1392 __ movl(EAX, Address(EBX, count_offset));
1384 __ addl(EAX, Immediate(Smi::RawValue(1))); 1393 __ addl(EAX, Immediate(Smi::RawValue(1)));
1385 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue))); 1394 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue)));
1386 __ cmovno(EDI, EAX); 1395 __ cmovno(EDI, EAX);
1387 __ movl(Address(EBX, count_offset), EDI); 1396 __ StoreIntoSmiField(Address(EBX, count_offset), EDI);
1388 1397
1389 __ movl(EAX, Address(EBX, target_offset)); 1398 __ movl(EAX, Address(EBX, target_offset));
1390 __ Bind(&call_target_function); 1399 __ Bind(&call_target_function);
1391 // EAX: Target function. 1400 // EAX: Target function.
1392 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset())); 1401 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset()));
1393 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1402 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1394 __ jmp(EBX); 1403 __ jmp(EBX);
1395 __ int3(); 1404 __ int3();
1396 1405
1397 __ Bind(&stepping); 1406 __ Bind(&stepping);
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
1943 const Register temp = ECX; 1952 const Register temp = ECX;
1944 __ movl(left, Address(ESP, 2 * kWordSize)); 1953 __ movl(left, Address(ESP, 2 * kWordSize));
1945 __ movl(right, Address(ESP, 1 * kWordSize)); 1954 __ movl(right, Address(ESP, 1 * kWordSize));
1946 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 1955 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
1947 __ ret(); 1956 __ ret();
1948 } 1957 }
1949 1958
1950 } // namespace dart 1959 } // namespace dart
1951 1960
1952 #endif // defined TARGET_ARCH_IA32 1961 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698