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

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

Issue 314983002: X87: Improve write barriers in optimized code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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/x87/macro-assembler-x87.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_X87 7 #if V8_TARGET_ARCH_X87
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 j(not_sign, &done, Label::kNear); 308 j(not_sign, &done, Label::kNear);
309 ExternalReference uint32_bias = 309 ExternalReference uint32_bias =
310 ExternalReference::address_of_uint32_bias(); 310 ExternalReference::address_of_uint32_bias();
311 fld_d(Operand::StaticVariable(uint32_bias)); 311 fld_d(Operand::StaticVariable(uint32_bias));
312 faddp(1); 312 faddp(1);
313 bind(&done); 313 bind(&done);
314 add(esp, Immediate(kPointerSize)); 314 add(esp, Immediate(kPointerSize));
315 } 315 }
316 316
317 317
318 void MacroAssembler::RecordWriteArray(Register object, 318 void MacroAssembler::RecordWriteArray(
319 Register value, 319 Register object,
320 Register index, 320 Register value,
321 RememberedSetAction remembered_set_action, 321 Register index,
322 SmiCheck smi_check) { 322 RememberedSetAction remembered_set_action,
323 SmiCheck smi_check,
324 PointersToHereCheck pointers_to_here_check_for_value) {
323 // First, check if a write barrier is even needed. The tests below 325 // First, check if a write barrier is even needed. The tests below
324 // catch stores of Smis. 326 // catch stores of Smis.
325 Label done; 327 Label done;
326 328
327 // Skip barrier if writing a smi. 329 // Skip barrier if writing a smi.
328 if (smi_check == INLINE_SMI_CHECK) { 330 if (smi_check == INLINE_SMI_CHECK) {
329 ASSERT_EQ(0, kSmiTag); 331 ASSERT_EQ(0, kSmiTag);
330 test(value, Immediate(kSmiTagMask)); 332 test(value, Immediate(kSmiTagMask));
331 j(zero, &done); 333 j(zero, &done);
332 } 334 }
333 335
334 // Array access: calculate the destination address in the same manner as 336 // Array access: calculate the destination address in the same manner as
335 // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset 337 // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset
336 // into an array of words. 338 // into an array of words.
337 Register dst = index; 339 Register dst = index;
338 lea(dst, Operand(object, index, times_half_pointer_size, 340 lea(dst, Operand(object, index, times_half_pointer_size,
339 FixedArray::kHeaderSize - kHeapObjectTag)); 341 FixedArray::kHeaderSize - kHeapObjectTag));
340 342
341 RecordWrite( 343 RecordWrite(object, dst, value, remembered_set_action, OMIT_SMI_CHECK,
342 object, dst, value, remembered_set_action, OMIT_SMI_CHECK); 344 pointers_to_here_check_for_value);
343 345
344 bind(&done); 346 bind(&done);
345 347
346 // Clobber clobbered input registers when running with the debug-code flag 348 // Clobber clobbered input registers when running with the debug-code flag
347 // turned on to provoke errors. 349 // turned on to provoke errors.
348 if (emit_debug_code()) { 350 if (emit_debug_code()) {
349 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 351 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
350 mov(index, Immediate(BitCast<int32_t>(kZapValue))); 352 mov(index, Immediate(BitCast<int32_t>(kZapValue)));
351 } 353 }
352 } 354 }
353 355
354 356
355 void MacroAssembler::RecordWriteField( 357 void MacroAssembler::RecordWriteField(
356 Register object, 358 Register object,
357 int offset, 359 int offset,
358 Register value, 360 Register value,
359 Register dst, 361 Register dst,
360 RememberedSetAction remembered_set_action, 362 RememberedSetAction remembered_set_action,
361 SmiCheck smi_check) { 363 SmiCheck smi_check,
364 PointersToHereCheck pointers_to_here_check_for_value) {
362 // First, check if a write barrier is even needed. The tests below 365 // First, check if a write barrier is even needed. The tests below
363 // catch stores of Smis. 366 // catch stores of Smis.
364 Label done; 367 Label done;
365 368
366 // Skip barrier if writing a smi. 369 // Skip barrier if writing a smi.
367 if (smi_check == INLINE_SMI_CHECK) { 370 if (smi_check == INLINE_SMI_CHECK) {
368 JumpIfSmi(value, &done, Label::kNear); 371 JumpIfSmi(value, &done, Label::kNear);
369 } 372 }
370 373
371 // Although the object register is tagged, the offset is relative to the start 374 // Although the object register is tagged, the offset is relative to the start
372 // of the object, so so offset must be a multiple of kPointerSize. 375 // of the object, so so offset must be a multiple of kPointerSize.
373 ASSERT(IsAligned(offset, kPointerSize)); 376 ASSERT(IsAligned(offset, kPointerSize));
374 377
375 lea(dst, FieldOperand(object, offset)); 378 lea(dst, FieldOperand(object, offset));
376 if (emit_debug_code()) { 379 if (emit_debug_code()) {
377 Label ok; 380 Label ok;
378 test_b(dst, (1 << kPointerSizeLog2) - 1); 381 test_b(dst, (1 << kPointerSizeLog2) - 1);
379 j(zero, &ok, Label::kNear); 382 j(zero, &ok, Label::kNear);
380 int3(); 383 int3();
381 bind(&ok); 384 bind(&ok);
382 } 385 }
383 386
384 RecordWrite( 387 RecordWrite(object, dst, value, remembered_set_action, OMIT_SMI_CHECK,
385 object, dst, value, remembered_set_action, OMIT_SMI_CHECK); 388 pointers_to_here_check_for_value);
386 389
387 bind(&done); 390 bind(&done);
388 391
389 // Clobber clobbered input registers when running with the debug-code flag 392 // Clobber clobbered input registers when running with the debug-code flag
390 // turned on to provoke errors. 393 // turned on to provoke errors.
391 if (emit_debug_code()) { 394 if (emit_debug_code()) {
392 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 395 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
393 mov(dst, Immediate(BitCast<int32_t>(kZapValue))); 396 mov(dst, Immediate(BitCast<int32_t>(kZapValue)));
394 } 397 }
395 } 398 }
(...skipping 19 matching lines...) Expand all
415 418
416 ASSERT(!object.is(value)); 419 ASSERT(!object.is(value));
417 ASSERT(!object.is(address)); 420 ASSERT(!object.is(address));
418 ASSERT(!value.is(address)); 421 ASSERT(!value.is(address));
419 AssertNotSmi(object); 422 AssertNotSmi(object);
420 423
421 if (!FLAG_incremental_marking) { 424 if (!FLAG_incremental_marking) {
422 return; 425 return;
423 } 426 }
424 427
428 // Compute the address.
429 lea(address, FieldOperand(object, HeapObject::kMapOffset));
430
425 // Count number of write barriers in generated code. 431 // Count number of write barriers in generated code.
426 isolate()->counters()->write_barriers_static()->Increment(); 432 isolate()->counters()->write_barriers_static()->Increment();
427 IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 433 IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1);
428 434
429 // A single check of the map's pages interesting flag suffices, since it is 435 // A single check of the map's pages interesting flag suffices, since it is
430 // only set during incremental collection, and then it's also guaranteed that 436 // only set during incremental collection, and then it's also guaranteed that
431 // the from object's page's interesting flag is also set. This optimization 437 // the from object's page's interesting flag is also set. This optimization
432 // relies on the fact that maps can never be in new space. 438 // relies on the fact that maps can never be in new space.
433 ASSERT(!isolate()->heap()->InNewSpace(*map)); 439 ASSERT(!isolate()->heap()->InNewSpace(*map));
434 CheckPageFlagForMap(map, 440 CheckPageFlagForMap(map,
435 MemoryChunk::kPointersToHereAreInterestingMask, 441 MemoryChunk::kPointersToHereAreInterestingMask,
436 zero, 442 zero,
437 &done, 443 &done,
438 Label::kNear); 444 Label::kNear);
439 445
440 // Delay the initialization of |address| and |value| for the stub until it's
441 // known that the will be needed. Up until this point their values are not
442 // needed since they are embedded in the operands of instructions that need
443 // them.
444 lea(address, FieldOperand(object, HeapObject::kMapOffset));
445 mov(value, Immediate(map));
446 RecordWriteStub stub(isolate(), object, value, address, OMIT_REMEMBERED_SET); 446 RecordWriteStub stub(isolate(), object, value, address, OMIT_REMEMBERED_SET);
447 CallStub(&stub); 447 CallStub(&stub);
448 448
449 bind(&done); 449 bind(&done);
450 450
451 // Clobber clobbered input registers when running with the debug-code flag 451 // Clobber clobbered input registers when running with the debug-code flag
452 // turned on to provoke errors. 452 // turned on to provoke errors.
453 if (emit_debug_code()) { 453 if (emit_debug_code()) {
454 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 454 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
455 mov(scratch1, Immediate(BitCast<int32_t>(kZapValue))); 455 mov(scratch1, Immediate(BitCast<int32_t>(kZapValue)));
456 mov(scratch2, Immediate(BitCast<int32_t>(kZapValue))); 456 mov(scratch2, Immediate(BitCast<int32_t>(kZapValue)));
457 } 457 }
458 } 458 }
459 459
460 460
461 void MacroAssembler::RecordWrite(Register object, 461 void MacroAssembler::RecordWrite(
462 Register address, 462 Register object,
463 Register value, 463 Register address,
464 RememberedSetAction remembered_set_action, 464 Register value,
465 SmiCheck smi_check) { 465 RememberedSetAction remembered_set_action,
466 SmiCheck smi_check,
467 PointersToHereCheck pointers_to_here_check_for_value) {
466 ASSERT(!object.is(value)); 468 ASSERT(!object.is(value));
467 ASSERT(!object.is(address)); 469 ASSERT(!object.is(address));
468 ASSERT(!value.is(address)); 470 ASSERT(!value.is(address));
469 AssertNotSmi(object); 471 AssertNotSmi(object);
470 472
471 if (remembered_set_action == OMIT_REMEMBERED_SET && 473 if (remembered_set_action == OMIT_REMEMBERED_SET &&
472 !FLAG_incremental_marking) { 474 !FLAG_incremental_marking) {
473 return; 475 return;
474 } 476 }
475 477
(...skipping 11 matching lines...) Expand all
487 489
488 // First, check if a write barrier is even needed. The tests below 490 // First, check if a write barrier is even needed. The tests below
489 // catch stores of Smis and stores into young gen. 491 // catch stores of Smis and stores into young gen.
490 Label done; 492 Label done;
491 493
492 if (smi_check == INLINE_SMI_CHECK) { 494 if (smi_check == INLINE_SMI_CHECK) {
493 // Skip barrier if writing a smi. 495 // Skip barrier if writing a smi.
494 JumpIfSmi(value, &done, Label::kNear); 496 JumpIfSmi(value, &done, Label::kNear);
495 } 497 }
496 498
497 CheckPageFlag(value, 499 if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) {
498 value, // Used as scratch. 500 CheckPageFlag(value,
499 MemoryChunk::kPointersToHereAreInterestingMask, 501 value, // Used as scratch.
500 zero, 502 MemoryChunk::kPointersToHereAreInterestingMask,
501 &done, 503 zero,
502 Label::kNear); 504 &done,
505 Label::kNear);
506 }
503 CheckPageFlag(object, 507 CheckPageFlag(object,
504 value, // Used as scratch. 508 value, // Used as scratch.
505 MemoryChunk::kPointersFromHereAreInterestingMask, 509 MemoryChunk::kPointersFromHereAreInterestingMask,
506 zero, 510 zero,
507 &done, 511 &done,
508 Label::kNear); 512 Label::kNear);
509 513
510 RecordWriteStub stub(isolate(), object, value, address, 514 RecordWriteStub stub(isolate(), object, value, address,
511 remembered_set_action); 515 remembered_set_action);
512 CallStub(&stub); 516 CallStub(&stub);
(...skipping 2775 matching lines...) Expand 10 before | Expand all | Expand 10 after
3288 if (ms.shift() > 0) sar(edx, ms.shift()); 3292 if (ms.shift() > 0) sar(edx, ms.shift());
3289 mov(eax, dividend); 3293 mov(eax, dividend);
3290 shr(eax, 31); 3294 shr(eax, 31);
3291 add(edx, eax); 3295 add(edx, eax);
3292 } 3296 }
3293 3297
3294 3298
3295 } } // namespace v8::internal 3299 } } // namespace v8::internal
3296 3300
3297 #endif // V8_TARGET_ARCH_X87 3301 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/x87/macro-assembler-x87.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698