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

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

Issue 7639015: ARM: Optimize stubs for incremental marking. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Incorporated second review by Erik Corry. Created 9 years, 4 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/arm/macro-assembler-arm.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 Label done; 485 Label done;
486 486
487 if (smi_check == INLINE_SMI_CHECK) { 487 if (smi_check == INLINE_SMI_CHECK) {
488 ASSERT_EQ(0, kSmiTag); 488 ASSERT_EQ(0, kSmiTag);
489 tst(value, Operand(kSmiTagMask)); 489 tst(value, Operand(kSmiTagMask));
490 b(eq, &done); 490 b(eq, &done);
491 } 491 }
492 492
493 CheckPageFlag(value, 493 CheckPageFlag(value,
494 value, // Used as scratch. 494 value, // Used as scratch.
495 MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING, 495 MemoryChunk::kPointersToHereAreInterestingMask,
496 eq, 496 eq,
497 &done); 497 &done);
498 CheckPageFlag(object, 498 CheckPageFlag(object,
499 value, // Used as scratch. 499 value, // Used as scratch.
500 MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING, 500 MemoryChunk::kPointersFromHereAreInterestingMask,
501 eq, 501 eq,
502 &done); 502 &done);
503 503
504 // Record the actual write. 504 // Record the actual write.
505 if (lr_status == kLRHasNotBeenSaved) { 505 if (lr_status == kLRHasNotBeenSaved) {
506 push(lr); 506 push(lr);
507 } 507 }
508 RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode); 508 RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode);
509 CallStub(&stub); 509 CallStub(&stub);
510 if (lr_status == kLRHasNotBeenSaved) { 510 if (lr_status == kLRHasNotBeenSaved) {
(...skipping 2682 matching lines...) Expand 10 before | Expand all | Expand 10 after
3193 // Get the address of the constant. 3193 // Get the address of the constant.
3194 and_(result, result, Operand(kLdrOffsetMask)); 3194 and_(result, result, Operand(kLdrOffsetMask));
3195 add(result, ldr_location, Operand(result)); 3195 add(result, ldr_location, Operand(result));
3196 add(result, result, Operand(kPCRegOffset)); 3196 add(result, result, Operand(kPCRegOffset));
3197 } 3197 }
3198 3198
3199 3199
3200 void MacroAssembler::CheckPageFlag( 3200 void MacroAssembler::CheckPageFlag(
3201 Register object, 3201 Register object,
3202 Register scratch, 3202 Register scratch,
3203 MemoryChunk::MemoryChunkFlags flag, 3203 int mask,
3204 Condition cc, 3204 Condition cc,
3205 Label* condition_met) { 3205 Label* condition_met) {
3206 and_(scratch, object, Operand(~Page::kPageAlignmentMask)); 3206 and_(scratch, object, Operand(~Page::kPageAlignmentMask));
3207 ldr(scratch, MemOperand(scratch, MemoryChunk::kFlagsOffset)); 3207 ldr(scratch, MemOperand(scratch, MemoryChunk::kFlagsOffset));
3208 tst(scratch, Operand(1 << flag)); 3208 tst(scratch, Operand(mask));
3209 b(cc, condition_met); 3209 b(cc, condition_met);
3210 } 3210 }
3211 3211
3212 3212
3213 void MacroAssembler::JumpIfBlack(Register object, 3213 void MacroAssembler::JumpIfBlack(Register object,
3214 Register scratch0, 3214 Register scratch0,
3215 Register scratch1, 3215 Register scratch1,
3216 Label* on_black) { 3216 Label* on_black) {
3217 HasColor(object, scratch0, scratch1, on_black, 1, 0); // kBlackBitPattern. 3217 HasColor(object, scratch0, scratch1, on_black, 1, 0); // kBlackBitPattern.
3218 ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 3218 ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3276 and_(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask)); 3276 and_(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask));
3277 Ubfx(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2); 3277 Ubfx(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2);
3278 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2; 3278 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2;
3279 Ubfx(ip, addr_reg, kLowBits, kPageSizeBits - kLowBits); 3279 Ubfx(ip, addr_reg, kLowBits, kPageSizeBits - kLowBits);
3280 add(bitmap_reg, bitmap_reg, Operand(ip, LSL, kPointerSizeLog2)); 3280 add(bitmap_reg, bitmap_reg, Operand(ip, LSL, kPointerSizeLog2));
3281 mov(ip, Operand(1)); 3281 mov(ip, Operand(1));
3282 mov(mask_reg, Operand(ip, LSL, mask_reg)); 3282 mov(mask_reg, Operand(ip, LSL, mask_reg));
3283 } 3283 }
3284 3284
3285 3285
3286 void MacroAssembler::EnsureNotWhite(
3287 Register value,
3288 Register bitmap_scratch,
3289 Register mask_scratch,
3290 Register load_scratch,
3291 Label* value_is_white_and_not_data) {
3292 ASSERT(!AreAliased(value, bitmap_scratch, mask_scratch, ip));
3293 GetMarkBits(value, bitmap_scratch, mask_scratch);
3294
3295 // If the value is black or grey we don't need to do anything.
3296 ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0);
3297 ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0);
3298 ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0);
3299 ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
3300
3301 Label done;
3302
3303 // Since both black and grey have a 1 in the first position and white does
3304 // not have a 1 there we only need to check one bit.
3305 ldr(load_scratch, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
3306 tst(mask_scratch, load_scratch);
3307 b(ne, &done);
3308
3309 if (FLAG_debug_code) {
3310 // Check for impossible bit pattern.
3311 Label ok;
3312 // LSL may overflow, making the check conservative.
3313 tst(load_scratch, Operand(mask_scratch, LSL, 1));
3314 b(eq, &ok);
3315 stop("Impossible marking bit pattern");
3316 bind(&ok);
3317 }
3318
3319 // Value is white. We check whether it is data that doesn't need scanning.
3320 // Currently only checks for HeapNumber and non-cons strings.
3321 Register map = load_scratch; // Holds map while checking type.
3322 Register length = load_scratch; // Holds length of object after testing type.
3323 Label is_data_object;
3324
3325 // Check for heap-number
3326 ldr(map, FieldMemOperand(value, HeapObject::kMapOffset));
3327 CompareRoot(map, Heap::kHeapNumberMapRootIndex);
3328 mov(length, Operand(HeapNumber::kSize), LeaveCC, eq);
3329 b(eq, &is_data_object);
3330
3331 // Check for strings.
3332 ASSERT(kConsStringTag == 1 && kIsConsStringMask == 1);
3333 ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80);
3334 // If it's a string and it's not a cons string then it's an object containing
3335 // no GC pointers.
3336 Register instance_type = load_scratch;
3337 ldrb(instance_type, FieldMemOperand(map, Map::kInstanceTypeOffset));
3338 tst(instance_type, Operand(kIsConsStringMask | kIsNotStringMask));
3339 b(ne, value_is_white_and_not_data);
3340 // It's a non-cons string.
3341 // If it's external, the length is just ExternalString::kSize.
3342 // Otherwise it's String::kHeaderSize + string->length() * (1 or 2).
3343 // External strings are the only ones with the kExternalStringTag bit
3344 // set.
3345 ASSERT_EQ(0, kSeqStringTag & kExternalStringTag);
3346 ASSERT_EQ(0, kConsStringTag & kExternalStringTag);
3347 tst(instance_type, Operand(kExternalStringTag));
3348 mov(length, Operand(ExternalString::kSize), LeaveCC, ne);
3349 b(ne, &is_data_object);
3350
3351 // Sequential string, either ASCII or UC16.
3352 // For ASCII (char-size of 1) we shift the smi tag away to get the length.
3353 // For UC16 (char-size of 2) we just leave the smi tag in place, thereby
3354 // getting the length multiplied by 2.
3355 ASSERT(kAsciiStringTag == 4 && kStringEncodingMask == 4);
3356 ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
3357 ldr(ip, FieldMemOperand(value, String::kLengthOffset));
3358 tst(instance_type, Operand(kStringEncodingMask));
3359 mov(ip, Operand(ip, LSR, 1), LeaveCC, ne);
3360 add(length, ip, Operand(SeqString::kHeaderSize + kObjectAlignmentMask));
3361 and_(length, length, Operand(~kObjectAlignmentMask));
3362
3363 bind(&is_data_object);
3364 // Value is a data object, and it is white. Mark it black. Since we know
3365 // that the object is white we can make it black by flipping one bit.
3366 ldr(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
3367 orr(ip, ip, Operand(mask_scratch));
3368 str(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
3369
3370 and_(bitmap_scratch, bitmap_scratch, Operand(~Page::kPageAlignmentMask));
3371 ldr(ip, MemOperand(bitmap_scratch, MemoryChunk::kLiveBytesOffset));
3372 add(ip, ip, Operand(length));
3373 str(ip, MemOperand(bitmap_scratch, MemoryChunk::kLiveBytesOffset));
3374
3375 bind(&done);
3376 }
3377
3378
3286 void MacroAssembler::ClampUint8(Register output_reg, Register input_reg) { 3379 void MacroAssembler::ClampUint8(Register output_reg, Register input_reg) {
3287 Usat(output_reg, 8, Operand(input_reg)); 3380 Usat(output_reg, 8, Operand(input_reg));
3288 } 3381 }
3289 3382
3290 3383
3291 void MacroAssembler::ClampDoubleToUint8(Register result_reg, 3384 void MacroAssembler::ClampDoubleToUint8(Register result_reg,
3292 DoubleRegister input_reg, 3385 DoubleRegister input_reg,
3293 DoubleRegister temp_double_reg) { 3386 DoubleRegister temp_double_reg) {
3294 Label above_zero; 3387 Label above_zero;
3295 Label done; 3388 Label done;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
3378 void CodePatcher::EmitCondition(Condition cond) { 3471 void CodePatcher::EmitCondition(Condition cond) {
3379 Instr instr = Assembler::instr_at(masm_.pc_); 3472 Instr instr = Assembler::instr_at(masm_.pc_);
3380 instr = (instr & ~kCondMask) | cond; 3473 instr = (instr & ~kCondMask) | cond;
3381 masm_.emit(instr); 3474 masm_.emit(instr);
3382 } 3475 }
3383 3476
3384 3477
3385 } } // namespace v8::internal 3478 } } // namespace v8::internal
3386 3479
3387 #endif // V8_TARGET_ARCH_ARM 3480 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698