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

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 297763006: Improve write barriers in optimized code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE Created 6 years, 6 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 | « src/x64/macro-assembler-x64.h ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 } 285 }
286 286
287 287
288 void MacroAssembler::RecordWriteField( 288 void MacroAssembler::RecordWriteField(
289 Register object, 289 Register object,
290 int offset, 290 int offset,
291 Register value, 291 Register value,
292 Register dst, 292 Register dst,
293 SaveFPRegsMode save_fp, 293 SaveFPRegsMode save_fp,
294 RememberedSetAction remembered_set_action, 294 RememberedSetAction remembered_set_action,
295 SmiCheck smi_check) { 295 SmiCheck smi_check,
296 PointersToHereCheck pointers_to_here_check_for_value) {
296 // First, check if a write barrier is even needed. The tests below 297 // First, check if a write barrier is even needed. The tests below
297 // catch stores of Smis. 298 // catch stores of Smis.
298 Label done; 299 Label done;
299 300
300 // Skip barrier if writing a smi. 301 // Skip barrier if writing a smi.
301 if (smi_check == INLINE_SMI_CHECK) { 302 if (smi_check == INLINE_SMI_CHECK) {
302 JumpIfSmi(value, &done); 303 JumpIfSmi(value, &done);
303 } 304 }
304 305
305 // Although the object register is tagged, the offset is relative to the start 306 // Although the object register is tagged, the offset is relative to the start
306 // of the object, so so offset must be a multiple of kPointerSize. 307 // of the object, so so offset must be a multiple of kPointerSize.
307 ASSERT(IsAligned(offset, kPointerSize)); 308 ASSERT(IsAligned(offset, kPointerSize));
308 309
309 leap(dst, FieldOperand(object, offset)); 310 leap(dst, FieldOperand(object, offset));
310 if (emit_debug_code()) { 311 if (emit_debug_code()) {
311 Label ok; 312 Label ok;
312 testb(dst, Immediate((1 << kPointerSizeLog2) - 1)); 313 testb(dst, Immediate((1 << kPointerSizeLog2) - 1));
313 j(zero, &ok, Label::kNear); 314 j(zero, &ok, Label::kNear);
314 int3(); 315 int3();
315 bind(&ok); 316 bind(&ok);
316 } 317 }
317 318
318 RecordWrite( 319 RecordWrite(object, dst, value, save_fp, remembered_set_action,
319 object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK); 320 OMIT_SMI_CHECK, pointers_to_here_check_for_value);
320 321
321 bind(&done); 322 bind(&done);
322 323
323 // Clobber clobbered input registers when running with the debug-code flag 324 // Clobber clobbered input registers when running with the debug-code flag
324 // turned on to provoke errors. 325 // turned on to provoke errors.
325 if (emit_debug_code()) { 326 if (emit_debug_code()) {
326 Move(value, kZapValue, Assembler::RelocInfoNone()); 327 Move(value, kZapValue, Assembler::RelocInfoNone());
327 Move(dst, kZapValue, Assembler::RelocInfoNone()); 328 Move(dst, kZapValue, Assembler::RelocInfoNone());
328 } 329 }
329 } 330 }
330 331
331 332
332 void MacroAssembler::RecordWriteArray(Register object, 333 void MacroAssembler::RecordWriteArray(
333 Register value, 334 Register object,
334 Register index, 335 Register value,
335 SaveFPRegsMode save_fp, 336 Register index,
336 RememberedSetAction remembered_set_action, 337 SaveFPRegsMode save_fp,
337 SmiCheck smi_check) { 338 RememberedSetAction remembered_set_action,
339 SmiCheck smi_check,
340 PointersToHereCheck pointers_to_here_check_for_value) {
338 // First, check if a write barrier is even needed. The tests below 341 // First, check if a write barrier is even needed. The tests below
339 // catch stores of Smis. 342 // catch stores of Smis.
340 Label done; 343 Label done;
341 344
342 // Skip barrier if writing a smi. 345 // Skip barrier if writing a smi.
343 if (smi_check == INLINE_SMI_CHECK) { 346 if (smi_check == INLINE_SMI_CHECK) {
344 JumpIfSmi(value, &done); 347 JumpIfSmi(value, &done);
345 } 348 }
346 349
347 // Array access: calculate the destination address. Index is not a smi. 350 // Array access: calculate the destination address. Index is not a smi.
348 Register dst = index; 351 Register dst = index;
349 leap(dst, Operand(object, index, times_pointer_size, 352 leap(dst, Operand(object, index, times_pointer_size,
350 FixedArray::kHeaderSize - kHeapObjectTag)); 353 FixedArray::kHeaderSize - kHeapObjectTag));
351 354
352 RecordWrite( 355 RecordWrite(object, dst, value, save_fp, remembered_set_action,
353 object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK); 356 OMIT_SMI_CHECK, pointers_to_here_check_for_value);
354 357
355 bind(&done); 358 bind(&done);
356 359
357 // Clobber clobbered input registers when running with the debug-code flag 360 // Clobber clobbered input registers when running with the debug-code flag
358 // turned on to provoke errors. 361 // turned on to provoke errors.
359 if (emit_debug_code()) { 362 if (emit_debug_code()) {
360 Move(value, kZapValue, Assembler::RelocInfoNone()); 363 Move(value, kZapValue, Assembler::RelocInfoNone());
361 Move(index, kZapValue, Assembler::RelocInfoNone()); 364 Move(index, kZapValue, Assembler::RelocInfoNone());
362 } 365 }
363 } 366 }
364 367
365 368
366 void MacroAssembler::RecordWrite(Register object, 369 void MacroAssembler::RecordWriteForMap(Register object,
367 Register address, 370 Register map,
368 Register value, 371 Register dst,
369 SaveFPRegsMode fp_mode, 372 SaveFPRegsMode fp_mode) {
370 RememberedSetAction remembered_set_action, 373 ASSERT(!object.is(kScratchRegister));
371 SmiCheck smi_check) { 374 ASSERT(!object.is(map));
375 ASSERT(!object.is(dst));
376 ASSERT(!map.is(dst));
377 AssertNotSmi(object);
378
379 if (emit_debug_code()) {
380 Label ok;
381 if (map.is(kScratchRegister)) pushq(map);
382 CompareMap(map, isolate()->factory()->meta_map());
383 if (map.is(kScratchRegister)) popq(map);
384 j(equal, &ok, Label::kNear);
385 int3();
386 bind(&ok);
387 }
388
389 if (!FLAG_incremental_marking) {
390 return;
391 }
392
393 if (emit_debug_code()) {
394 Label ok;
395 if (map.is(kScratchRegister)) pushq(map);
396 cmpp(map, FieldOperand(object, HeapObject::kMapOffset));
397 if (map.is(kScratchRegister)) popq(map);
398 j(equal, &ok, Label::kNear);
399 int3();
400 bind(&ok);
401 }
402
403 // Compute the address.
404 leap(dst, FieldOperand(object, HeapObject::kMapOffset));
405
406 // Count number of write barriers in generated code.
407 isolate()->counters()->write_barriers_static()->Increment();
408 IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1);
409
410 // First, check if a write barrier is even needed. The tests below
411 // catch stores of smis and stores into the young generation.
412 Label done;
413
414 // A single check of the map's pages interesting flag suffices, since it is
415 // only set during incremental collection, and then it's also guaranteed that
416 // the from object's page's interesting flag is also set. This optimization
417 // relies on the fact that maps can never be in new space.
418 CheckPageFlag(map,
419 map, // Used as scratch.
420 MemoryChunk::kPointersToHereAreInterestingMask,
421 zero,
422 &done,
423 Label::kNear);
424
425 RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET,
426 fp_mode);
427 CallStub(&stub);
428
429 bind(&done);
430
431 // Clobber clobbered registers when running with the debug-code flag
432 // turned on to provoke errors.
433 if (emit_debug_code()) {
434 Move(dst, kZapValue, Assembler::RelocInfoNone());
435 Move(map, kZapValue, Assembler::RelocInfoNone());
436 }
437 }
438
439
440 void MacroAssembler::RecordWrite(
441 Register object,
442 Register address,
443 Register value,
444 SaveFPRegsMode fp_mode,
445 RememberedSetAction remembered_set_action,
446 SmiCheck smi_check,
447 PointersToHereCheck pointers_to_here_check_for_value) {
372 ASSERT(!object.is(value)); 448 ASSERT(!object.is(value));
373 ASSERT(!object.is(address)); 449 ASSERT(!object.is(address));
374 ASSERT(!value.is(address)); 450 ASSERT(!value.is(address));
375 AssertNotSmi(object); 451 AssertNotSmi(object);
376 452
377 if (remembered_set_action == OMIT_REMEMBERED_SET && 453 if (remembered_set_action == OMIT_REMEMBERED_SET &&
378 !FLAG_incremental_marking) { 454 !FLAG_incremental_marking) {
379 return; 455 return;
380 } 456 }
381 457
(...skipping 11 matching lines...) Expand all
393 469
394 // First, check if a write barrier is even needed. The tests below 470 // First, check if a write barrier is even needed. The tests below
395 // catch stores of smis and stores into the young generation. 471 // catch stores of smis and stores into the young generation.
396 Label done; 472 Label done;
397 473
398 if (smi_check == INLINE_SMI_CHECK) { 474 if (smi_check == INLINE_SMI_CHECK) {
399 // Skip barrier if writing a smi. 475 // Skip barrier if writing a smi.
400 JumpIfSmi(value, &done); 476 JumpIfSmi(value, &done);
401 } 477 }
402 478
403 CheckPageFlag(value, 479 if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) {
404 value, // Used as scratch. 480 CheckPageFlag(value,
405 MemoryChunk::kPointersToHereAreInterestingMask, 481 value, // Used as scratch.
406 zero, 482 MemoryChunk::kPointersToHereAreInterestingMask,
407 &done, 483 zero,
408 Label::kNear); 484 &done,
485 Label::kNear);
486 }
409 487
410 CheckPageFlag(object, 488 CheckPageFlag(object,
411 value, // Used as scratch. 489 value, // Used as scratch.
412 MemoryChunk::kPointersFromHereAreInterestingMask, 490 MemoryChunk::kPointersFromHereAreInterestingMask,
413 zero, 491 zero,
414 &done, 492 &done,
415 Label::kNear); 493 Label::kNear);
416 494
417 RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, 495 RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
418 fp_mode); 496 fp_mode);
(...skipping 4758 matching lines...) Expand 10 before | Expand all | Expand 10 after
5177 if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift())); 5255 if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift()));
5178 movl(rax, dividend); 5256 movl(rax, dividend);
5179 shrl(rax, Immediate(31)); 5257 shrl(rax, Immediate(31));
5180 addl(rdx, rax); 5258 addl(rdx, rax);
5181 } 5259 }
5182 5260
5183 5261
5184 } } // namespace v8::internal 5262 } } // namespace v8::internal
5185 5263
5186 #endif // V8_TARGET_ARCH_X64 5264 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698