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

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

Issue 13925024: Implements write barrier on MIPS. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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
« no previous file with comments | « runtime/vm/assembler_mips.h ('k') | runtime/vm/assembler_mips_test.cc » ('j') | 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_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/runtime_entry.h" 9 #include "vm/runtime_entry.h"
10 #include "vm/simulator.h" 10 #include "vm/simulator.h"
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 } 201 }
202 202
203 203
204 void Assembler::CompareObject(Register rd, Register rn, const Object& object) { 204 void Assembler::CompareObject(Register rd, Register rn, const Object& object) {
205 ASSERT(rn != TMP1); 205 ASSERT(rn != TMP1);
206 LoadObject(TMP1, object); 206 LoadObject(TMP1, object);
207 subu(rd, rn, TMP1); 207 subu(rd, rn, TMP1);
208 } 208 }
209 209
210 210
211 // Preserves object and value registers.
212 void Assembler::StoreIntoObjectFilterNoSmi(Register object,
213 Register value,
214 Label* no_update) {
215 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
216 (kOldObjectAlignmentOffset == 0), young_alignment);
217
218 // Write-barrier triggers if the value is in the new space (has bit set) and
219 // the object is in the old space (has bit cleared).
220 // To check that, we compute value & ~object and skip the write barrier
221 // if the bit is not set. We can't destroy the object.
222 nor(TMP1, ZR, object);
223 and_(TMP1, value, TMP1);
224 andi(TMP1, TMP1, Immediate(kNewObjectAlignmentOffset));
225 beq(TMP1, ZR, no_update);
226 }
227
228
229 // Preserves object and value registers.
230 void Assembler::StoreIntoObjectFilter(Register object,
231 Register value,
232 Label* no_update) {
233 // For the value we are only interested in the new/old bit and the tag bit.
234 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi.
235 sll(TMP1, value, kObjectAlignmentLog2 - 1);
236 and_(TMP1, value, TMP1);
237 // And the result with the negated space bit of the object.
238 nor(TMP2, ZR, object);
239 and_(TMP1, TMP1, TMP2);
240 andi(TMP1, TMP1, Immediate(kNewObjectAlignmentOffset));
241 beq(TMP1, ZR, no_update);
242 }
243
244
245 void Assembler::StoreIntoObject(Register object,
246 const Address& dest,
247 Register value,
248 bool can_value_be_smi) {
249 ASSERT(object != value);
250 sw(value, dest);
251 Label done;
252 if (can_value_be_smi) {
253 StoreIntoObjectFilter(object, value, &done);
254 } else {
255 StoreIntoObjectFilterNoSmi(object, value, &done);
256 }
257 // A store buffer update is required.
258 if (value != T0) Push(T0); // Preserve T0.
259 if (object != T0) {
260 mov(T0, object);
261 }
262 BranchLink(&StubCode::UpdateStoreBufferLabel());
263 if (value != T0) Pop(T0); // Restore T0.
264 Bind(&done);
265 }
266
267
268 void Assembler::StoreIntoObjectNoBarrier(Register object,
269 const Address& dest,
270 Register value) {
271 sw(value, dest);
272 #if defined(DEBUG)
273 Label done;
274 StoreIntoObjectFilter(object, value, &done);
275 Stop("Store buffer update is required");
276 Bind(&done);
277 #endif // defined(DEBUG)
278 // No store buffer update.
279 }
280
281
282 void Assembler::StoreIntoObjectNoBarrier(Register object,
283 const Address& dest,
284 const Object& value) {
285 ASSERT(value.IsSmi() || value.InVMHeap() ||
286 (value.IsOld() && value.IsNotTemporaryScopedHandle()));
287 // No store buffer update.
288 LoadObject(TMP1, value);
289 sw(TMP1, dest);
290 }
291
292
211 void Assembler::LoadClassId(Register result, Register object) { 293 void Assembler::LoadClassId(Register result, Register object) {
212 ASSERT(RawObject::kClassIdTagBit == 16); 294 ASSERT(RawObject::kClassIdTagBit == 16);
213 ASSERT(RawObject::kClassIdTagSize == 16); 295 ASSERT(RawObject::kClassIdTagSize == 16);
214 const intptr_t class_id_offset = Object::tags_offset() + 296 const intptr_t class_id_offset = Object::tags_offset() +
215 RawObject::kClassIdTagBit / kBitsPerByte; 297 RawObject::kClassIdTagBit / kBitsPerByte;
216 lhu(result, FieldAddress(object, class_id_offset)); 298 lhu(result, FieldAddress(object, class_id_offset));
217 } 299 }
218 300
219 301
220 void Assembler::LoadClassById(Register result, Register class_id) { 302 void Assembler::LoadClassById(Register result, Register class_id) {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 // Reserve space for arguments and align frame before entering 435 // Reserve space for arguments and align frame before entering
354 // the C++ world. 436 // the C++ world.
355 AddImmediate(SP, -frame_space); 437 AddImmediate(SP, -frame_space);
356 if (OS::ActivationFrameAlignment() > 0) { 438 if (OS::ActivationFrameAlignment() > 0) {
357 LoadImmediate(TMP1, ~(OS::ActivationFrameAlignment() - 1)); 439 LoadImmediate(TMP1, ~(OS::ActivationFrameAlignment() - 1));
358 and_(SP, SP, TMP1); 440 and_(SP, SP, TMP1);
359 } 441 }
360 } 442 }
361 443
362 444
445 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
446 const intptr_t kPushedRegistersSize =
447 kDartVolatileCpuRegCount * kWordSize +
448 2 * kWordSize + // FP and RA.
449 kDartVolatileFpuRegCount * kWordSize;
450
451 if (prologue_offset_ == -1) {
452 prologue_offset_ = CodeSize();
453 }
454
455 // Save volatile CPU and FPU registers on the stack:
456 // -------------
457 // FPU Registers
458 // CPU Registers
459 // RA
460 // FP
461 // -------------
regis 2013/04/16 00:16:38 I would add a TODO to verify that this layout is u
zra 2013/04/16 00:24:42 Done.
462 addiu(SP, SP, Immediate(-kPushedRegistersSize));
463 for (int i = kDartFirstVolatileFpuReg; i <= kDartLastVolatileFpuReg; i++) {
464 // These go above the volatile CPU registers.
465 const int slot =
466 (i - kDartFirstVolatileFpuReg) + kDartVolatileCpuRegCount + 2;
467 FRegister reg = static_cast<FRegister>(i);
468 swc1(reg, Address(SP, slot * kWordSize));
469 }
470 for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) {
471 // + 2 because FP goes in slot 0.
472 const int slot = (i - kDartFirstVolatileCpuReg) + 2;
473 Register reg = static_cast<Register>(i);
474 sw(reg, Address(SP, slot * kWordSize));
475 }
476 sw(RA, Address(SP, 1 * kWordSize));
477 sw(FP, Address(SP, 0 * kWordSize));
478 mov(FP, SP);
479
480 ReserveAlignedFrameSpace(frame_space);
481 }
482
483
484 void Assembler::LeaveCallRuntimeFrame() {
485 const intptr_t kPushedRegistersSize =
486 kDartVolatileCpuRegCount * kWordSize +
487 2 * kWordSize + // FP and RA.
488 kDartVolatileFpuRegCount * kWordSize;
489
490 // SP might have been modified to reserve space for arguments
491 // and ensure proper alignment of the stack frame.
492 // We need to restore it before restoring registers.
493 mov(SP, FP);
494
495 // Restore volatile CPU and FPU registers from the stack.
496 lw(FP, Address(SP, 0 * kWordSize));
497 lw(RA, Address(SP, 1 * kWordSize));
498 for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) {
499 // + 2 because FP goes in slot 0.
500 const int slot = (i - kDartFirstVolatileCpuReg) + 2;
501 Register reg = static_cast<Register>(i);
502 lw(reg, Address(SP, slot * kWordSize));
503 }
504 for (int i = kDartFirstVolatileFpuReg; i <= kDartLastVolatileFpuReg; i++) {
505 // These go above the volatile CPU registers.
506 const int slot =
507 (i - kDartFirstVolatileFpuReg) + kDartVolatileCpuRegCount + 2;
508 FRegister reg = static_cast<FRegister>(i);
509 lwc1(reg, Address(SP, slot * kWordSize));
510 }
511 addiu(SP, SP, Immediate(kPushedRegistersSize));
512 }
513
514
363 int32_t Assembler::AddExternalLabel(const ExternalLabel* label) { 515 int32_t Assembler::AddExternalLabel(const ExternalLabel* label) {
364 if (object_pool_.IsNull()) { 516 if (object_pool_.IsNull()) {
365 // The object pool cannot be used in the vm isolate. 517 // The object pool cannot be used in the vm isolate.
366 ASSERT(Isolate::Current() != Dart::vm_isolate()); 518 ASSERT(Isolate::Current() != Dart::vm_isolate());
367 object_pool_ = GrowableObjectArray::New(Heap::kOld); 519 object_pool_ = GrowableObjectArray::New(Heap::kOld);
368 } 520 }
369 const word address = label->address(); 521 const word address = label->address();
370 ASSERT(Utils::IsAligned(address, 4)); 522 ASSERT(Utils::IsAligned(address, 4));
371 // The address is stored in the object array as a RawSmi. 523 // The address is stored in the object array as a RawSmi.
372 const Smi& smi = Smi::Handle(Smi::New(address >> kSmiTagShift)); 524 const Smi& smi = Smi::Handle(Smi::New(address >> kSmiTagShift));
(...skipping 12 matching lines...) Expand all
385 b(&stop); 537 b(&stop);
386 Emit(reinterpret_cast<int32_t>(message)); 538 Emit(reinterpret_cast<int32_t>(message));
387 Bind(&stop); 539 Bind(&stop);
388 break_(Instr::kStopMessageCode); 540 break_(Instr::kStopMessageCode);
389 } 541 }
390 542
391 } // namespace dart 543 } // namespace dart
392 544
393 #endif // defined TARGET_ARCH_MIPS 545 #endif // defined TARGET_ARCH_MIPS
394 546
OLDNEW
« no previous file with comments | « runtime/vm/assembler_mips.h ('k') | runtime/vm/assembler_mips_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698