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

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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 430 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
431 __ LeaveFrame(); 431 __ LeaveFrame();
432 __ jmp(EAX); 432 __ jmp(EAX);
433 __ int3(); 433 __ int3();
434 } 434 }
435 435
436 436
437 // Input parameters: 437 // Input parameters:
438 // EDX: smi-tagged argument count, may be zero. 438 // EDX: smi-tagged argument count, may be zero.
439 // EBP[kParamEndSlotFromFp + 1]: last argument. 439 // EBP[kParamEndSlotFromFp + 1]: last argument.
440 // Uses EAX, EBX, ECX, EDX. 440 // Uses EAX, EBX, ECX, EDX, EDI.
441 static void PushArgumentsArray(Assembler* assembler) { 441 static void PushArgumentsArray(Assembler* assembler) {
442 const Immediate& raw_null = 442 const Immediate& raw_null =
443 Immediate(reinterpret_cast<intptr_t>(Object::null())); 443 Immediate(reinterpret_cast<intptr_t>(Object::null()));
444 StubCode* stub_code = Isolate::Current()->stub_code(); 444 StubCode* stub_code = Isolate::Current()->stub_code();
445 445
446 // Allocate array to store arguments of caller. 446 // Allocate array to store arguments of caller.
447 __ movl(ECX, raw_null); // Null element type for raw Array. 447 __ movl(ECX, raw_null); // Null element type for raw Array.
448 const Code& array_stub = Code::Handle(stub_code->GetAllocateArrayStub()); 448 const Code& array_stub = Code::Handle(stub_code->GetAllocateArrayStub());
449 const ExternalLabel array_label(array_stub.EntryPoint()); 449 const ExternalLabel array_label(array_stub.EntryPoint());
450 __ call(&array_label); 450 __ call(&array_label);
451 __ SmiUntag(EDX); 451 __ SmiUntag(EDX);
452 // EAX: newly allocated array. 452 // EAX: newly allocated array.
453 // EDX: length of the array (was preserved by the stub). 453 // EDX: length of the array (was preserved by the stub).
454 __ pushl(EAX); // Array is in EAX and on top of stack. 454 __ pushl(EAX); // Array is in EAX and on top of stack.
455 __ leal(EBX, Address(EBP, EDX, TIMES_4, kParamEndSlotFromFp * kWordSize)); 455 __ leal(EBX, Address(EBP, EDX, TIMES_4, kParamEndSlotFromFp * kWordSize));
456 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); 456 __ leal(ECX, FieldAddress(EAX, Array::data_offset()));
457 // EBX: address of first argument on stack. 457 // EBX: address of first argument on stack.
458 // ECX: address of first argument in array. 458 // ECX: address of first argument in array.
459 Label loop, loop_condition; 459 Label loop, loop_condition;
460 __ jmp(&loop_condition, Assembler::kNearJump); 460 __ jmp(&loop_condition, Assembler::kNearJump);
461 __ Bind(&loop); 461 __ Bind(&loop);
462 __ movl(EAX, Address(EBX, 0)); 462 __ movl(EDI, Address(EBX, 0));
463 __ movl(Address(ECX, 0), EAX); 463 // No generational barrier needed, since array is in new space.
464 __ StoreIntoObjectNoBarrier(EAX, Address(ECX, 0), EDI);
464 __ AddImmediate(ECX, Immediate(kWordSize)); 465 __ AddImmediate(ECX, Immediate(kWordSize));
465 __ AddImmediate(EBX, Immediate(-kWordSize)); 466 __ AddImmediate(EBX, Immediate(-kWordSize));
466 __ Bind(&loop_condition); 467 __ Bind(&loop_condition);
467 __ decl(EDX); 468 __ decl(EDX);
468 __ j(POSITIVE, &loop, Assembler::kNearJump); 469 __ j(POSITIVE, &loop, Assembler::kNearJump);
469 } 470 }
470 471
471 472
472 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 473 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
473 intptr_t deopt_reason, 474 intptr_t deopt_reason,
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 // EDI: iterator which initially points to the start of the variable 738 // EDI: iterator which initially points to the start of the variable
738 // data area to be initialized. 739 // data area to be initialized.
739 // ECX: array element type. 740 // ECX: array element type.
740 // EDX: array length as Smi. 741 // EDX: array length as Smi.
741 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray))); 742 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray)));
742 Label done; 743 Label done;
743 Label init_loop; 744 Label init_loop;
744 __ Bind(&init_loop); 745 __ Bind(&init_loop);
745 __ cmpl(EDI, EBX); 746 __ cmpl(EDI, EBX);
746 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); 747 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
747 __ movl(Address(EDI, 0), raw_null); 748 // No generational barrier needed, since we are storing null.
749 __ StoreIntoObjectNoBarrier(EAX, Address(EDI, 0), Object::null_object());
748 __ addl(EDI, Immediate(kWordSize)); 750 __ addl(EDI, Immediate(kWordSize));
749 __ jmp(&init_loop, Assembler::kNearJump); 751 __ jmp(&init_loop, Assembler::kNearJump);
750 __ Bind(&done); 752 __ Bind(&done);
751 __ ret(); // returns the newly allocated object in EAX. 753 __ ret(); // returns the newly allocated object in EAX.
752 754
753 // Unable to allocate the array using the fast inline code, just call 755 // Unable to allocate the array using the fast inline code, just call
754 // into the runtime. 756 // into the runtime.
755 __ Bind(&slow_case); 757 __ Bind(&slow_case);
756 // Create a stub frame as we are pushing some objects on the stack before 758 // Create a stub frame as we are pushing some objects on the stack before
757 // calling into the runtime. 759 // calling into the runtime.
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 __ orl(EBX, 983 __ orl(EBX,
982 Immediate(RawObject::ClassIdTag::encode(cid))); 984 Immediate(RawObject::ClassIdTag::encode(cid)));
983 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags. 985 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags.
984 } 986 }
985 987
986 // Setup up number of context variables field. 988 // Setup up number of context variables field.
987 // EAX: new object. 989 // EAX: new object.
988 // EDX: number of context variables as integer value (not object). 990 // EDX: number of context variables as integer value (not object).
989 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); 991 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX);
990 992
991 const Immediate& raw_null =
992 Immediate(reinterpret_cast<intptr_t>(Object::null()));
993 // Setup the parent field. 993 // Setup the parent field.
994 // EAX: new object. 994 // EAX: new object.
995 // EDX: number of context variables. 995 // EDX: number of context variables.
996 __ movl(FieldAddress(EAX, Context::parent_offset()), raw_null); 996 // No generational barrier needed, since we are storing null.
997 __ StoreIntoObjectNoBarrier(EAX,
Ivan Posva 2014/10/29 07:58:41 Here and other places: In the long run we will nee
koda 2014/10/29 18:29:21 Yes, I was aware of that, and that also applies to
998 FieldAddress(EAX, Context::parent_offset()),
999 Object::null_object());
997 1000
998 // Initialize the context variables. 1001 // Initialize the context variables.
999 // EAX: new object. 1002 // EAX: new object.
1000 // EDX: number of context variables. 1003 // EDX: number of context variables.
1001 { 1004 {
1002 Label loop, entry; 1005 Label loop, entry;
1003 __ leal(EBX, FieldAddress(EAX, Context::variable_offset(0))); 1006 __ leal(EBX, FieldAddress(EAX, Context::variable_offset(0)));
1004 1007
1005 __ jmp(&entry, Assembler::kNearJump); 1008 __ jmp(&entry, Assembler::kNearJump);
1006 __ Bind(&loop); 1009 __ Bind(&loop);
1007 __ decl(EDX); 1010 __ decl(EDX);
1008 __ movl(Address(EBX, EDX, TIMES_4, 0), raw_null); 1011 // No generational barrier needed, since we are storing null.
1012 __ StoreIntoObjectNoBarrier(EAX,
1013 Address(EBX, EDX, TIMES_4, 0),
1014 Object::null_object());
1009 __ Bind(&entry); 1015 __ Bind(&entry);
1010 __ cmpl(EDX, Immediate(0)); 1016 __ cmpl(EDX, Immediate(0));
1011 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1017 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1012 } 1018 }
1013 1019
1014 // Done allocating and initializing the context. 1020 // Done allocating and initializing the context.
1015 // EAX: new object. 1021 // EAX: new object.
1016 __ ret(); 1022 __ ret();
1017 1023
1018 __ Bind(&slow_case); 1024 __ Bind(&slow_case);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 // EBX: potential next object start. 1157 // EBX: potential next object start.
1152 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); 1158 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space)));
1153 if (FLAG_use_slow_path) { 1159 if (FLAG_use_slow_path) {
1154 __ jmp(&slow_case); 1160 __ jmp(&slow_case);
1155 } else { 1161 } else {
1156 __ j(ABOVE_EQUAL, &slow_case); 1162 __ j(ABOVE_EQUAL, &slow_case);
1157 } 1163 }
1158 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); 1164 __ movl(Address::Absolute(heap->TopAddress(space)), EBX);
1159 __ UpdateAllocationStats(cls.id(), ECX, space); 1165 __ UpdateAllocationStats(cls.id(), ECX, space);
1160 1166
1161 // EAX: new object start. 1167 // EAX: new object start (untagged).
1162 // EBX: next object start. 1168 // EBX: next object start.
1163 // EDX: new object type arguments (if is_cls_parameterized). 1169 // EDX: new object type arguments (if is_cls_parameterized).
1164 // Set the tags. 1170 // Set the tags.
1165 uword tags = 0; 1171 uword tags = 0;
1166 tags = RawObject::SizeTag::update(instance_size, tags); 1172 tags = RawObject::SizeTag::update(instance_size, tags);
1167 ASSERT(cls.id() != kIllegalCid); 1173 ASSERT(cls.id() != kIllegalCid);
1168 tags = RawObject::ClassIdTag::update(cls.id(), tags); 1174 tags = RawObject::ClassIdTag::update(cls.id(), tags);
1169 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); 1175 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags));
1176 __ addl(EAX, Immediate(kHeapObjectTag));
1170 1177
1171 // Initialize the remaining words of the object. 1178 // Initialize the remaining words of the object.
1172 const Immediate& raw_null =
1173 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1174 1179
1175 // EAX: new object start. 1180 // EAX: new object (tagged).
1176 // EBX: next object start. 1181 // EBX: next object start.
1177 // EDX: new object type arguments (if is_cls_parameterized). 1182 // EDX: new object type arguments (if is_cls_parameterized).
1178 // First try inlining the initialization without a loop. 1183 // First try inlining the initialization without a loop.
1179 if (instance_size < (kInlineInstanceSize * kWordSize)) { 1184 if (instance_size < (kInlineInstanceSize * kWordSize)) {
1180 // Check if the object contains any non-header fields. 1185 // Check if the object contains any non-header fields.
1181 // Small objects are initialized using a consecutive set of writes. 1186 // Small objects are initialized using a consecutive set of writes.
1182 for (intptr_t current_offset = Instance::NextFieldOffset(); 1187 for (intptr_t current_offset = Instance::NextFieldOffset();
1183 current_offset < instance_size; 1188 current_offset < instance_size;
1184 current_offset += kWordSize) { 1189 current_offset += kWordSize) {
1185 __ movl(Address(EAX, current_offset), raw_null); 1190 __ StoreIntoObjectNoBarrier(EAX,
Ivan Posva 2014/10/29 07:58:41 ditto here and other places
1191 FieldAddress(EAX, current_offset),
1192 Object::null_object());
1186 } 1193 }
1187 } else { 1194 } else {
1188 __ leal(ECX, Address(EAX, Instance::NextFieldOffset())); 1195 __ leal(ECX, Address(EAX, Instance::NextFieldOffset()));
1189 // Loop until the whole object is initialized. 1196 // Loop until the whole object is initialized.
1190 // EAX: new object. 1197 // EAX: new object (tagged).
1191 // EBX: next object start. 1198 // EBX: next object start.
1192 // ECX: next word to be initialized. 1199 // ECX: next word to be initialized.
1193 // EDX: new object type arguments (if is_cls_parameterized). 1200 // EDX: new object type arguments (if is_cls_parameterized).
1194 Label init_loop; 1201 Label init_loop;
1195 Label done; 1202 Label done;
1196 __ Bind(&init_loop); 1203 __ Bind(&init_loop);
1197 __ cmpl(ECX, EBX); 1204 __ cmpl(ECX, EBX);
1198 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); 1205 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
1199 __ movl(Address(ECX, 0), raw_null); 1206 __ StoreIntoObjectNoBarrier(EAX,
1207 Address(ECX, 0),
1208 Object::null_object());
1200 __ addl(ECX, Immediate(kWordSize)); 1209 __ addl(ECX, Immediate(kWordSize));
1201 __ jmp(&init_loop, Assembler::kNearJump); 1210 __ jmp(&init_loop, Assembler::kNearJump);
1202 __ Bind(&done); 1211 __ Bind(&done);
1203 } 1212 }
1204 if (is_cls_parameterized) { 1213 if (is_cls_parameterized) {
1205 // EDX: new object type arguments. 1214 // EDX: new object type arguments.
1206 // Set the type arguments in the new object. 1215 // Set the type arguments in the new object.
1207 __ movl(Address(EAX, cls.type_arguments_field_offset()), EDX); 1216 intptr_t offset = cls.type_arguments_field_offset();
1217 __ StoreIntoObjectNoBarrier(EAX, FieldAddress(EAX, offset), EDX);
1208 } 1218 }
1209 // Done allocating and initializing the instance. 1219 // Done allocating and initializing the instance.
1210 // EAX: new object. 1220 // EAX: new object (tagged).
1211 __ addl(EAX, Immediate(kHeapObjectTag));
1212 __ ret(); 1221 __ ret();
1213 1222
1214 __ Bind(&slow_case); 1223 __ Bind(&slow_case);
1215 } 1224 }
1216 // If is_cls_parameterized: 1225 // If is_cls_parameterized:
1217 // EDX: new object type arguments. 1226 // EDX: new object type arguments.
1218 // Create a stub frame as we are pushing some objects on the stack before 1227 // Create a stub frame as we are pushing some objects on the stack before
1219 // calling into the runtime. 1228 // calling into the runtime.
1220 __ EnterStubFrame(); 1229 __ EnterStubFrame();
1221 __ pushl(raw_null); // Setup space on stack for return value. 1230 __ pushl(raw_null); // Setup space on stack for return value.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1362 __ Bind(&error); 1371 __ Bind(&error);
1363 __ Stop("Incorrect IC data"); 1372 __ Stop("Incorrect IC data");
1364 __ Bind(&ok); 1373 __ Bind(&ok);
1365 #endif 1374 #endif
1366 // Update counter. 1375 // Update counter.
1367 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1376 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1368 __ movl(ECX, Address(EBX, count_offset)); 1377 __ movl(ECX, Address(EBX, count_offset));
1369 __ addl(ECX, Immediate(Smi::RawValue(1))); 1378 __ addl(ECX, Immediate(Smi::RawValue(1)));
1370 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue))); 1379 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue)));
1371 __ cmovno(EDI, ECX); 1380 __ cmovno(EDI, ECX);
1372 __ movl(Address(EBX, count_offset), EDI); 1381 __ StoreIntoSmiField(Address(EBX, count_offset), EDI);
1373 1382
1374 __ ret(); 1383 __ ret();
1375 } 1384 }
1376 1385
1377 1386
1378 // Generate inline cache check for 'num_args'. 1387 // Generate inline cache check for 'num_args'.
1379 // ECX: Inline cache data object. 1388 // ECX: Inline cache data object.
1380 // TOS(0): return address 1389 // TOS(0): return address
1381 // Control flow: 1390 // Control flow:
1382 // - If receiver is null -> jump to IC miss. 1391 // - If receiver is null -> jump to IC miss.
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 __ Bind(&found); 1519 __ Bind(&found);
1511 // EBX: Pointer to an IC data check group. 1520 // EBX: Pointer to an IC data check group.
1512 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1521 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1513 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1522 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1514 1523
1515 // Update counter. 1524 // Update counter.
1516 __ movl(EAX, Address(EBX, count_offset)); 1525 __ movl(EAX, Address(EBX, count_offset));
1517 __ addl(EAX, Immediate(Smi::RawValue(1))); 1526 __ addl(EAX, Immediate(Smi::RawValue(1)));
1518 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue))); 1527 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue)));
1519 __ cmovno(EDI, EAX); 1528 __ cmovno(EDI, EAX);
1520 __ movl(Address(EBX, count_offset), EDI); 1529 __ StoreIntoSmiField(Address(EBX, count_offset), EDI);
1521 1530
1522 __ movl(EAX, Address(EBX, target_offset)); 1531 __ movl(EAX, Address(EBX, target_offset));
1523 __ Bind(&call_target_function); 1532 __ Bind(&call_target_function);
1524 // EAX: Target function. 1533 // EAX: Target function.
1525 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset())); 1534 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset()));
1526 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1535 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1527 __ jmp(EBX); 1536 __ jmp(EBX);
1528 __ int3(); 1537 __ int3();
1529 1538
1530 __ Bind(&stepping); 1539 __ Bind(&stepping);
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
2076 const Register temp = ECX; 2085 const Register temp = ECX;
2077 __ movl(left, Address(ESP, 2 * kWordSize)); 2086 __ movl(left, Address(ESP, 2 * kWordSize));
2078 __ movl(right, Address(ESP, 1 * kWordSize)); 2087 __ movl(right, Address(ESP, 1 * kWordSize));
2079 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2088 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2080 __ ret(); 2089 __ ret();
2081 } 2090 }
2082 2091
2083 } // namespace dart 2092 } // namespace dart
2084 2093
2085 #endif // defined TARGET_ARCH_IA32 2094 #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