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

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

Issue 1542113002: Do not mark from native code. Check color and call incremental marker instead. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « src/ppc/macro-assembler-ppc.h ('k') | src/x64/code-stubs-x64.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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 <assert.h> // For assert 5 #include <assert.h> // For assert
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_PPC 8 #if V8_TARGET_ARCH_PPC
9 9
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 3185 matching lines...) Expand 10 before | Expand all | Expand 10 after
3196 b(&other_color); 3196 b(&other_color);
3197 3197
3198 bind(&word_boundary); 3198 bind(&word_boundary);
3199 lwz(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize + kIntSize)); 3199 lwz(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize + kIntSize));
3200 andi(r0, ip, Operand(1)); 3200 andi(r0, ip, Operand(1));
3201 b(second_bit == 1 ? ne : eq, has_color, cr0); 3201 b(second_bit == 1 ? ne : eq, has_color, cr0);
3202 bind(&other_color); 3202 bind(&other_color);
3203 } 3203 }
3204 3204
3205 3205
3206 // Detect some, but not all, common pointer-free objects. This is used by the
3207 // incremental write barrier which doesn't care about oddballs (they are always
3208 // marked black immediately so this code is not hit).
3209 void MacroAssembler::JumpIfDataObject(Register value, Register scratch,
3210 Label* not_data_object) {
3211 Label is_data_object;
3212 LoadP(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
3213 CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
3214 beq(&is_data_object);
3215 DCHECK(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1);
3216 DCHECK(kNotStringTag == 0x80 && kIsNotStringMask == 0x80);
3217 // If it's a string and it's not a cons string then it's an object containing
3218 // no GC pointers.
3219 lbz(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
3220 STATIC_ASSERT((kIsIndirectStringMask | kIsNotStringMask) == 0x81);
3221 andi(scratch, scratch, Operand(kIsIndirectStringMask | kIsNotStringMask));
3222 bne(not_data_object, cr0);
3223 bind(&is_data_object);
3224 }
3225
3226
3227 void MacroAssembler::GetMarkBits(Register addr_reg, Register bitmap_reg, 3206 void MacroAssembler::GetMarkBits(Register addr_reg, Register bitmap_reg,
3228 Register mask_reg) { 3207 Register mask_reg) {
3229 DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg)); 3208 DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg));
3230 DCHECK((~Page::kPageAlignmentMask & 0xffff) == 0); 3209 DCHECK((~Page::kPageAlignmentMask & 0xffff) == 0);
3231 lis(r0, Operand((~Page::kPageAlignmentMask >> 16))); 3210 lis(r0, Operand((~Page::kPageAlignmentMask >> 16)));
3232 and_(bitmap_reg, addr_reg, r0); 3211 and_(bitmap_reg, addr_reg, r0);
3233 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2; 3212 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2;
3234 ExtractBitRange(mask_reg, addr_reg, kLowBits - 1, kPointerSizeLog2); 3213 ExtractBitRange(mask_reg, addr_reg, kLowBits - 1, kPointerSizeLog2);
3235 ExtractBitRange(ip, addr_reg, kPageSizeBits - 1, kLowBits); 3214 ExtractBitRange(ip, addr_reg, kPageSizeBits - 1, kLowBits);
3236 ShiftLeftImm(ip, ip, Operand(Bitmap::kBytesPerCellLog2)); 3215 ShiftLeftImm(ip, ip, Operand(Bitmap::kBytesPerCellLog2));
3237 add(bitmap_reg, bitmap_reg, ip); 3216 add(bitmap_reg, bitmap_reg, ip);
3238 li(ip, Operand(1)); 3217 li(ip, Operand(1));
3239 slw(mask_reg, ip, mask_reg); 3218 slw(mask_reg, ip, mask_reg);
3240 } 3219 }
3241 3220
3242 3221
3243 void MacroAssembler::EnsureNotWhite(Register value, Register bitmap_scratch, 3222 void MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch,
3244 Register mask_scratch, 3223 Register mask_scratch, Register load_scratch,
3245 Register load_scratch, 3224 Label* value_is_white) {
3246 Label* value_is_white_and_not_data) {
3247 DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, ip)); 3225 DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, ip));
3248 GetMarkBits(value, bitmap_scratch, mask_scratch); 3226 GetMarkBits(value, bitmap_scratch, mask_scratch);
3249 3227
3250 // If the value is black or grey we don't need to do anything. 3228 // If the value is black or grey we don't need to do anything.
3251 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 3229 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
3252 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); 3230 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0);
3253 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0); 3231 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0);
3254 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 3232 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
3255 3233
3256 Label done;
3257
3258 // Since both black and grey have a 1 in the first position and white does 3234 // Since both black and grey have a 1 in the first position and white does
3259 // not have a 1 there we only need to check one bit. 3235 // not have a 1 there we only need to check one bit.
3260 lwz(load_scratch, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3236 lwz(load_scratch, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
3261 and_(r0, mask_scratch, load_scratch, SetRC); 3237 and_(r0, mask_scratch, load_scratch, SetRC);
3262 bne(&done, cr0); 3238 beq(value_is_white, cr0);
3263
3264 if (emit_debug_code()) {
3265 // Check for impossible bit pattern.
3266 Label ok;
3267 // LSL may overflow, making the check conservative.
3268 slwi(r0, mask_scratch, Operand(1));
3269 and_(r0, load_scratch, r0, SetRC);
3270 beq(&ok, cr0);
3271 stop("Impossible marking bit pattern");
3272 bind(&ok);
3273 }
3274
3275 // Value is white. We check whether it is data that doesn't need scanning.
3276 // Currently only checks for HeapNumber and non-cons strings.
3277 Register map = load_scratch; // Holds map while checking type.
3278 Register length = load_scratch; // Holds length of object after testing type.
3279 Label is_data_object, maybe_string_object, is_string_object, is_encoded;
3280 #if V8_TARGET_ARCH_PPC64
3281 Label length_computed;
3282 #endif
3283
3284
3285 // Check for heap-number
3286 LoadP(map, FieldMemOperand(value, HeapObject::kMapOffset));
3287 CompareRoot(map, Heap::kHeapNumberMapRootIndex);
3288 bne(&maybe_string_object);
3289 li(length, Operand(HeapNumber::kSize));
3290 b(&is_data_object);
3291 bind(&maybe_string_object);
3292
3293 // Check for strings.
3294 DCHECK(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1);
3295 DCHECK(kNotStringTag == 0x80 && kIsNotStringMask == 0x80);
3296 // If it's a string and it's not a cons string then it's an object containing
3297 // no GC pointers.
3298 Register instance_type = load_scratch;
3299 lbz(instance_type, FieldMemOperand(map, Map::kInstanceTypeOffset));
3300 andi(r0, instance_type, Operand(kIsIndirectStringMask | kIsNotStringMask));
3301 bne(value_is_white_and_not_data, cr0);
3302 // It's a non-indirect (non-cons and non-slice) string.
3303 // If it's external, the length is just ExternalString::kSize.
3304 // Otherwise it's String::kHeaderSize + string->length() * (1 or 2).
3305 // External strings are the only ones with the kExternalStringTag bit
3306 // set.
3307 DCHECK_EQ(0, kSeqStringTag & kExternalStringTag);
3308 DCHECK_EQ(0, kConsStringTag & kExternalStringTag);
3309 andi(r0, instance_type, Operand(kExternalStringTag));
3310 beq(&is_string_object, cr0);
3311 li(length, Operand(ExternalString::kSize));
3312 b(&is_data_object);
3313 bind(&is_string_object);
3314
3315 // Sequential string, either Latin1 or UC16.
3316 // For Latin1 (char-size of 1) we untag the smi to get the length.
3317 // For UC16 (char-size of 2):
3318 // - (32-bit) we just leave the smi tag in place, thereby getting
3319 // the length multiplied by 2.
3320 // - (64-bit) we compute the offset in the 2-byte array
3321 DCHECK(kOneByteStringTag == 4 && kStringEncodingMask == 4);
3322 LoadP(ip, FieldMemOperand(value, String::kLengthOffset));
3323 andi(r0, instance_type, Operand(kStringEncodingMask));
3324 beq(&is_encoded, cr0);
3325 SmiUntag(ip);
3326 #if V8_TARGET_ARCH_PPC64
3327 b(&length_computed);
3328 #endif
3329 bind(&is_encoded);
3330 #if V8_TARGET_ARCH_PPC64
3331 SmiToShortArrayOffset(ip, ip);
3332 bind(&length_computed);
3333 #else
3334 DCHECK(kSmiShift == 1);
3335 #endif
3336 addi(length, ip, Operand(SeqString::kHeaderSize + kObjectAlignmentMask));
3337 li(r0, Operand(~kObjectAlignmentMask));
3338 and_(length, length, r0);
3339
3340 bind(&is_data_object);
3341 // Value is a data object, and it is white. Mark it black. Since we know
3342 // that the object is white we can make it black by flipping one bit.
3343 lwz(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
3344 orx(ip, ip, mask_scratch);
3345 stw(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
3346
3347 mov(ip, Operand(~Page::kPageAlignmentMask));
3348 and_(bitmap_scratch, bitmap_scratch, ip);
3349 lwz(ip, MemOperand(bitmap_scratch, MemoryChunk::kLiveBytesOffset));
3350 add(ip, ip, length);
3351 stw(ip, MemOperand(bitmap_scratch, MemoryChunk::kLiveBytesOffset));
3352
3353 bind(&done);
3354 } 3239 }
3355 3240
3356 3241
3357 // Saturate a value into 8-bit unsigned integer 3242 // Saturate a value into 8-bit unsigned integer
3358 // if input_value < 0, output_value is 0 3243 // if input_value < 0, output_value is 0
3359 // if input_value > 255, output_value is 255 3244 // if input_value > 255, output_value is 255
3360 // otherwise output_value is the input_value 3245 // otherwise output_value is the input_value
3361 void MacroAssembler::ClampUint8(Register output_reg, Register input_reg) { 3246 void MacroAssembler::ClampUint8(Register output_reg, Register input_reg) {
3362 int satval = (1 << 8) - 1; 3247 int satval = (1 << 8) - 1;
3363 3248
(...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after
4404 } 4289 }
4405 if (mag.shift > 0) srawi(result, result, mag.shift); 4290 if (mag.shift > 0) srawi(result, result, mag.shift);
4406 ExtractBit(r0, dividend, 31); 4291 ExtractBit(r0, dividend, 31);
4407 add(result, result, r0); 4292 add(result, result, r0);
4408 } 4293 }
4409 4294
4410 } // namespace internal 4295 } // namespace internal
4411 } // namespace v8 4296 } // namespace v8
4412 4297
4413 #endif // V8_TARGET_ARCH_PPC 4298 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/ppc/macro-assembler-ppc.h ('k') | src/x64/code-stubs-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698