OLD | NEW |
1 | 1 |
2 // Copyright 2012 the V8 project authors. All rights reserved. | 2 // Copyright 2012 the V8 project authors. All rights reserved. |
3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
5 | 5 |
6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
7 | 7 |
8 #if V8_TARGET_ARCH_MIPS | 8 #if V8_TARGET_ARCH_MIPS |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 5410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5421 jmp(&other_color); | 5421 jmp(&other_color); |
5422 | 5422 |
5423 bind(&word_boundary); | 5423 bind(&word_boundary); |
5424 lw(t9, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize + kPointerSize)); | 5424 lw(t9, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize + kPointerSize)); |
5425 And(t9, t9, Operand(1)); | 5425 And(t9, t9, Operand(1)); |
5426 Branch(has_color, second_bit == 1 ? ne : eq, t9, Operand(zero_reg)); | 5426 Branch(has_color, second_bit == 1 ? ne : eq, t9, Operand(zero_reg)); |
5427 bind(&other_color); | 5427 bind(&other_color); |
5428 } | 5428 } |
5429 | 5429 |
5430 | 5430 |
5431 // Detect some, but not all, common pointer-free objects. This is used by the | |
5432 // incremental write barrier which doesn't care about oddballs (they are always | |
5433 // marked black immediately so this code is not hit). | |
5434 void MacroAssembler::JumpIfDataObject(Register value, | |
5435 Register scratch, | |
5436 Label* not_data_object) { | |
5437 DCHECK(!AreAliased(value, scratch, t8, no_reg)); | |
5438 Label is_data_object; | |
5439 lw(scratch, FieldMemOperand(value, HeapObject::kMapOffset)); | |
5440 LoadRoot(t8, Heap::kHeapNumberMapRootIndex); | |
5441 Branch(&is_data_object, eq, t8, Operand(scratch)); | |
5442 DCHECK(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); | |
5443 DCHECK(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); | |
5444 // If it's a string and it's not a cons string then it's an object containing | |
5445 // no GC pointers. | |
5446 lbu(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); | |
5447 And(t8, scratch, Operand(kIsIndirectStringMask | kIsNotStringMask)); | |
5448 Branch(not_data_object, ne, t8, Operand(zero_reg)); | |
5449 bind(&is_data_object); | |
5450 } | |
5451 | |
5452 | |
5453 void MacroAssembler::GetMarkBits(Register addr_reg, | 5431 void MacroAssembler::GetMarkBits(Register addr_reg, |
5454 Register bitmap_reg, | 5432 Register bitmap_reg, |
5455 Register mask_reg) { | 5433 Register mask_reg) { |
5456 DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg)); | 5434 DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg)); |
5457 And(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask)); | 5435 And(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask)); |
5458 Ext(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2); | 5436 Ext(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2); |
5459 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2; | 5437 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2; |
5460 Ext(t8, addr_reg, kLowBits, kPageSizeBits - kLowBits); | 5438 Ext(t8, addr_reg, kLowBits, kPageSizeBits - kLowBits); |
5461 sll(t8, t8, kPointerSizeLog2); | 5439 sll(t8, t8, kPointerSizeLog2); |
5462 Addu(bitmap_reg, bitmap_reg, t8); | 5440 Addu(bitmap_reg, bitmap_reg, t8); |
5463 li(t8, Operand(1)); | 5441 li(t8, Operand(1)); |
5464 sllv(mask_reg, t8, mask_reg); | 5442 sllv(mask_reg, t8, mask_reg); |
5465 } | 5443 } |
5466 | 5444 |
5467 | 5445 |
5468 void MacroAssembler::EnsureNotWhite( | 5446 void MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, |
5469 Register value, | 5447 Register mask_scratch, Register load_scratch, |
5470 Register bitmap_scratch, | 5448 Label* value_is_white) { |
5471 Register mask_scratch, | |
5472 Register load_scratch, | |
5473 Label* value_is_white_and_not_data) { | |
5474 DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, t8)); | 5449 DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, t8)); |
5475 GetMarkBits(value, bitmap_scratch, mask_scratch); | 5450 GetMarkBits(value, bitmap_scratch, mask_scratch); |
5476 | 5451 |
5477 // If the value is black or grey we don't need to do anything. | 5452 // If the value is black or grey we don't need to do anything. |
5478 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); | 5453 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); |
5479 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); | 5454 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); |
5480 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0); | 5455 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0); |
5481 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); | 5456 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); |
5482 | 5457 |
5483 Label done; | |
5484 | |
5485 // Since both black and grey have a 1 in the first position and white does | 5458 // Since both black and grey have a 1 in the first position and white does |
5486 // not have a 1 there we only need to check one bit. | 5459 // not have a 1 there we only need to check one bit. |
5487 lw(load_scratch, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize)); | 5460 lw(load_scratch, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize)); |
5488 And(t8, mask_scratch, load_scratch); | 5461 And(t8, mask_scratch, load_scratch); |
5489 Branch(&done, ne, t8, Operand(zero_reg)); | 5462 Branch(value_is_white, eq, t8, Operand(zero_reg)); |
5490 | |
5491 if (emit_debug_code()) { | |
5492 // Check for impossible bit pattern. | |
5493 Label ok; | |
5494 // sll may overflow, making the check conservative. | |
5495 sll(t8, mask_scratch, 1); | |
5496 And(t8, load_scratch, t8); | |
5497 Branch(&ok, eq, t8, Operand(zero_reg)); | |
5498 stop("Impossible marking bit pattern"); | |
5499 bind(&ok); | |
5500 } | |
5501 | |
5502 // Value is white. We check whether it is data that doesn't need scanning. | |
5503 // Currently only checks for HeapNumber and non-cons strings. | |
5504 Register map = load_scratch; // Holds map while checking type. | |
5505 Register length = load_scratch; // Holds length of object after testing type. | |
5506 Label is_data_object; | |
5507 | |
5508 // Check for heap-number | |
5509 lw(map, FieldMemOperand(value, HeapObject::kMapOffset)); | |
5510 LoadRoot(t8, Heap::kHeapNumberMapRootIndex); | |
5511 { | |
5512 Label skip; | |
5513 Branch(&skip, ne, t8, Operand(map)); | |
5514 li(length, HeapNumber::kSize); | |
5515 Branch(&is_data_object); | |
5516 bind(&skip); | |
5517 } | |
5518 | |
5519 // Check for strings. | |
5520 DCHECK(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); | |
5521 DCHECK(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); | |
5522 // If it's a string and it's not a cons string then it's an object containing | |
5523 // no GC pointers. | |
5524 Register instance_type = load_scratch; | |
5525 lbu(instance_type, FieldMemOperand(map, Map::kInstanceTypeOffset)); | |
5526 And(t8, instance_type, Operand(kIsIndirectStringMask | kIsNotStringMask)); | |
5527 Branch(value_is_white_and_not_data, ne, t8, Operand(zero_reg)); | |
5528 // It's a non-indirect (non-cons and non-slice) string. | |
5529 // If it's external, the length is just ExternalString::kSize. | |
5530 // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). | |
5531 // External strings are the only ones with the kExternalStringTag bit | |
5532 // set. | |
5533 DCHECK_EQ(0, kSeqStringTag & kExternalStringTag); | |
5534 DCHECK_EQ(0, kConsStringTag & kExternalStringTag); | |
5535 And(t8, instance_type, Operand(kExternalStringTag)); | |
5536 { | |
5537 Label skip; | |
5538 Branch(&skip, eq, t8, Operand(zero_reg)); | |
5539 li(length, ExternalString::kSize); | |
5540 Branch(&is_data_object); | |
5541 bind(&skip); | |
5542 } | |
5543 | |
5544 // Sequential string, either Latin1 or UC16. | |
5545 // For Latin1 (char-size of 1) we shift the smi tag away to get the length. | |
5546 // For UC16 (char-size of 2) we just leave the smi tag in place, thereby | |
5547 // getting the length multiplied by 2. | |
5548 DCHECK(kOneByteStringTag == 4 && kStringEncodingMask == 4); | |
5549 DCHECK(kSmiTag == 0 && kSmiTagSize == 1); | |
5550 lw(t9, FieldMemOperand(value, String::kLengthOffset)); | |
5551 And(t8, instance_type, Operand(kStringEncodingMask)); | |
5552 { | |
5553 Label skip; | |
5554 Branch(&skip, eq, t8, Operand(zero_reg)); | |
5555 srl(t9, t9, 1); | |
5556 bind(&skip); | |
5557 } | |
5558 Addu(length, t9, Operand(SeqString::kHeaderSize + kObjectAlignmentMask)); | |
5559 And(length, length, Operand(~kObjectAlignmentMask)); | |
5560 | |
5561 bind(&is_data_object); | |
5562 // Value is a data object, and it is white. Mark it black. Since we know | |
5563 // that the object is white we can make it black by flipping one bit. | |
5564 lw(t8, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize)); | |
5565 Or(t8, t8, Operand(mask_scratch)); | |
5566 sw(t8, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize)); | |
5567 | |
5568 And(bitmap_scratch, bitmap_scratch, Operand(~Page::kPageAlignmentMask)); | |
5569 lw(t8, MemOperand(bitmap_scratch, MemoryChunk::kLiveBytesOffset)); | |
5570 Addu(t8, t8, Operand(length)); | |
5571 sw(t8, MemOperand(bitmap_scratch, MemoryChunk::kLiveBytesOffset)); | |
5572 | |
5573 bind(&done); | |
5574 } | 5463 } |
5575 | 5464 |
5576 | 5465 |
5577 void MacroAssembler::LoadInstanceDescriptors(Register map, | 5466 void MacroAssembler::LoadInstanceDescriptors(Register map, |
5578 Register descriptors) { | 5467 Register descriptors) { |
5579 lw(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset)); | 5468 lw(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset)); |
5580 } | 5469 } |
5581 | 5470 |
5582 | 5471 |
5583 void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { | 5472 void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5864 if (mag.shift > 0) sra(result, result, mag.shift); | 5753 if (mag.shift > 0) sra(result, result, mag.shift); |
5865 srl(at, dividend, 31); | 5754 srl(at, dividend, 31); |
5866 Addu(result, result, Operand(at)); | 5755 Addu(result, result, Operand(at)); |
5867 } | 5756 } |
5868 | 5757 |
5869 | 5758 |
5870 } // namespace internal | 5759 } // namespace internal |
5871 } // namespace v8 | 5760 } // namespace v8 |
5872 | 5761 |
5873 #endif // V8_TARGET_ARCH_MIPS | 5762 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |