OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 bind(&done); | 389 bind(&done); |
390 } else { | 390 } else { |
391 usat(dst, satpos, src, cond); | 391 usat(dst, satpos, src, cond); |
392 } | 392 } |
393 } | 393 } |
394 | 394 |
395 | 395 |
396 void MacroAssembler::LoadRoot(Register destination, | 396 void MacroAssembler::LoadRoot(Register destination, |
397 Heap::RootListIndex index, | 397 Heap::RootListIndex index, |
398 Condition cond) { | 398 Condition cond) { |
399 ldr(destination, MemOperand(roots, index << kPointerSizeLog2), cond); | 399 ldr(destination, MemOperand(kRootRegister, index << kPointerSizeLog2), cond); |
400 } | 400 } |
401 | 401 |
402 | 402 |
403 void MacroAssembler::StoreRoot(Register source, | 403 void MacroAssembler::StoreRoot(Register source, |
404 Heap::RootListIndex index, | 404 Heap::RootListIndex index, |
405 Condition cond) { | 405 Condition cond) { |
406 str(source, MemOperand(roots, index << kPointerSizeLog2), cond); | 406 str(source, MemOperand(kRootRegister, index << kPointerSizeLog2), cond); |
407 } | 407 } |
408 | 408 |
409 | 409 |
410 void MacroAssembler::LoadHeapObject(Register result, | 410 void MacroAssembler::LoadHeapObject(Register result, |
411 Handle<HeapObject> object) { | 411 Handle<HeapObject> object) { |
412 if (isolate()->heap()->InNewSpace(*object)) { | 412 if (isolate()->heap()->InNewSpace(*object)) { |
413 Handle<JSGlobalPropertyCell> cell = | 413 Handle<JSGlobalPropertyCell> cell = |
414 isolate()->factory()->NewJSGlobalPropertyCell(object); | 414 isolate()->factory()->NewJSGlobalPropertyCell(object); |
415 mov(result, Operand(cell)); | 415 mov(result, Operand(cell)); |
416 ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset)); | 416 ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset)); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 Register value, | 489 Register value, |
490 LinkRegisterStatus lr_status, | 490 LinkRegisterStatus lr_status, |
491 SaveFPRegsMode fp_mode, | 491 SaveFPRegsMode fp_mode, |
492 RememberedSetAction remembered_set_action, | 492 RememberedSetAction remembered_set_action, |
493 SmiCheck smi_check) { | 493 SmiCheck smi_check) { |
494 // The compiled code assumes that record write doesn't change the | 494 // The compiled code assumes that record write doesn't change the |
495 // context register, so we check that none of the clobbered | 495 // context register, so we check that none of the clobbered |
496 // registers are cp. | 496 // registers are cp. |
497 ASSERT(!address.is(cp) && !value.is(cp)); | 497 ASSERT(!address.is(cp) && !value.is(cp)); |
498 | 498 |
499 if (FLAG_debug_code) { | 499 if (emit_debug_code()) { |
500 Label ok; | |
501 ldr(ip, MemOperand(address)); | 500 ldr(ip, MemOperand(address)); |
502 cmp(ip, value); | 501 cmp(ip, value); |
503 b(eq, &ok); | 502 Check(eq, "Wrong address or value passed to RecordWrite"); |
504 stop("Wrong address or value passed to RecordWrite"); | |
505 bind(&ok); | |
506 } | 503 } |
507 | 504 |
508 Label done; | 505 Label done; |
509 | 506 |
510 if (smi_check == INLINE_SMI_CHECK) { | 507 if (smi_check == INLINE_SMI_CHECK) { |
511 ASSERT_EQ(0, kSmiTag); | 508 ASSERT_EQ(0, kSmiTag); |
512 tst(value, Operand(kSmiTagMask)); | 509 tst(value, Operand(kSmiTagMask)); |
513 b(eq, &done); | 510 b(eq, &done); |
514 } | 511 } |
515 | 512 |
(...skipping 28 matching lines...) Expand all Loading... |
544 } | 541 } |
545 } | 542 } |
546 | 543 |
547 | 544 |
548 void MacroAssembler::RememberedSetHelper(Register object, // For debug tests. | 545 void MacroAssembler::RememberedSetHelper(Register object, // For debug tests. |
549 Register address, | 546 Register address, |
550 Register scratch, | 547 Register scratch, |
551 SaveFPRegsMode fp_mode, | 548 SaveFPRegsMode fp_mode, |
552 RememberedSetFinalAction and_then) { | 549 RememberedSetFinalAction and_then) { |
553 Label done; | 550 Label done; |
554 if (FLAG_debug_code) { | 551 if (emit_debug_code()) { |
555 Label ok; | 552 Label ok; |
556 JumpIfNotInNewSpace(object, scratch, &ok); | 553 JumpIfNotInNewSpace(object, scratch, &ok); |
557 stop("Remembered set pointer is in new space"); | 554 stop("Remembered set pointer is in new space"); |
558 bind(&ok); | 555 bind(&ok); |
559 } | 556 } |
560 // Load store buffer top. | 557 // Load store buffer top. |
561 ExternalReference store_buffer = | 558 ExternalReference store_buffer = |
562 ExternalReference::store_buffer_top(isolate()); | 559 ExternalReference::store_buffer_top(isolate()); |
563 mov(ip, Operand(store_buffer)); | 560 mov(ip, Operand(store_buffer)); |
564 ldr(scratch, MemOperand(ip)); | 561 ldr(scratch, MemOperand(ip)); |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 // r2: preserved | 810 // r2: preserved |
814 | 811 |
815 // Drop the execution stack down to the frame pointer and restore | 812 // Drop the execution stack down to the frame pointer and restore |
816 // the caller frame pointer and return address. | 813 // the caller frame pointer and return address. |
817 mov(sp, fp); | 814 mov(sp, fp); |
818 ldm(ia_w, sp, fp.bit() | lr.bit()); | 815 ldm(ia_w, sp, fp.bit() | lr.bit()); |
819 } | 816 } |
820 | 817 |
821 | 818 |
822 void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { | 819 void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { |
823 // Setup the frame structure on the stack. | 820 // Set up the frame structure on the stack. |
824 ASSERT_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); | 821 ASSERT_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); |
825 ASSERT_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); | 822 ASSERT_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); |
826 ASSERT_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); | 823 ASSERT_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); |
827 Push(lr, fp); | 824 Push(lr, fp); |
828 mov(fp, Operand(sp)); // Setup new frame pointer. | 825 mov(fp, Operand(sp)); // Set up new frame pointer. |
829 // Reserve room for saved entry sp and code object. | 826 // Reserve room for saved entry sp and code object. |
830 sub(sp, sp, Operand(2 * kPointerSize)); | 827 sub(sp, sp, Operand(2 * kPointerSize)); |
831 if (emit_debug_code()) { | 828 if (emit_debug_code()) { |
832 mov(ip, Operand(0)); | 829 mov(ip, Operand(0)); |
833 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 830 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
834 } | 831 } |
835 mov(ip, Operand(CodeObject())); | 832 mov(ip, Operand(CodeObject())); |
836 str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); | 833 str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); |
837 | 834 |
838 // Save the frame pointer and the context in top. | 835 // Save the frame pointer and the context in top. |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1407 | 1404 |
1408 ldr(scratch, FieldMemOperand(scratch, token_offset)); | 1405 ldr(scratch, FieldMemOperand(scratch, token_offset)); |
1409 ldr(ip, FieldMemOperand(ip, token_offset)); | 1406 ldr(ip, FieldMemOperand(ip, token_offset)); |
1410 cmp(scratch, Operand(ip)); | 1407 cmp(scratch, Operand(ip)); |
1411 b(ne, miss); | 1408 b(ne, miss); |
1412 | 1409 |
1413 bind(&same_contexts); | 1410 bind(&same_contexts); |
1414 } | 1411 } |
1415 | 1412 |
1416 | 1413 |
| 1414 void MacroAssembler::GetNumberHash(Register t0, Register scratch) { |
| 1415 // First of all we assign the hash seed to scratch. |
| 1416 LoadRoot(scratch, Heap::kHashSeedRootIndex); |
| 1417 SmiUntag(scratch); |
| 1418 |
| 1419 // Xor original key with a seed. |
| 1420 eor(t0, t0, Operand(scratch)); |
| 1421 |
| 1422 // Compute the hash code from the untagged key. This must be kept in sync |
| 1423 // with ComputeIntegerHash in utils.h. |
| 1424 // |
| 1425 // hash = ~hash + (hash << 15); |
| 1426 mvn(scratch, Operand(t0)); |
| 1427 add(t0, scratch, Operand(t0, LSL, 15)); |
| 1428 // hash = hash ^ (hash >> 12); |
| 1429 eor(t0, t0, Operand(t0, LSR, 12)); |
| 1430 // hash = hash + (hash << 2); |
| 1431 add(t0, t0, Operand(t0, LSL, 2)); |
| 1432 // hash = hash ^ (hash >> 4); |
| 1433 eor(t0, t0, Operand(t0, LSR, 4)); |
| 1434 // hash = hash * 2057; |
| 1435 mov(scratch, Operand(t0, LSL, 11)); |
| 1436 add(t0, t0, Operand(t0, LSL, 3)); |
| 1437 add(t0, t0, scratch); |
| 1438 // hash = hash ^ (hash >> 16); |
| 1439 eor(t0, t0, Operand(t0, LSR, 16)); |
| 1440 } |
| 1441 |
| 1442 |
1417 void MacroAssembler::LoadFromNumberDictionary(Label* miss, | 1443 void MacroAssembler::LoadFromNumberDictionary(Label* miss, |
1418 Register elements, | 1444 Register elements, |
1419 Register key, | 1445 Register key, |
1420 Register result, | 1446 Register result, |
1421 Register t0, | 1447 Register t0, |
1422 Register t1, | 1448 Register t1, |
1423 Register t2) { | 1449 Register t2) { |
1424 // Register use: | 1450 // Register use: |
1425 // | 1451 // |
1426 // elements - holds the slow-case elements of the receiver on entry. | 1452 // elements - holds the slow-case elements of the receiver on entry. |
1427 // Unchanged unless 'result' is the same register. | 1453 // Unchanged unless 'result' is the same register. |
1428 // | 1454 // |
1429 // key - holds the smi key on entry. | 1455 // key - holds the smi key on entry. |
1430 // Unchanged unless 'result' is the same register. | 1456 // Unchanged unless 'result' is the same register. |
1431 // | 1457 // |
1432 // result - holds the result on exit if the load succeeded. | 1458 // result - holds the result on exit if the load succeeded. |
1433 // Allowed to be the same as 'key' or 'result'. | 1459 // Allowed to be the same as 'key' or 'result'. |
1434 // Unchanged on bailout so 'key' or 'result' can be used | 1460 // Unchanged on bailout so 'key' or 'result' can be used |
1435 // in further computation. | 1461 // in further computation. |
1436 // | 1462 // |
1437 // Scratch registers: | 1463 // Scratch registers: |
1438 // | 1464 // |
1439 // t0 - holds the untagged key on entry and holds the hash once computed. | 1465 // t0 - holds the untagged key on entry and holds the hash once computed. |
1440 // | 1466 // |
1441 // t1 - used to hold the capacity mask of the dictionary | 1467 // t1 - used to hold the capacity mask of the dictionary |
1442 // | 1468 // |
1443 // t2 - used for the index into the dictionary. | 1469 // t2 - used for the index into the dictionary. |
1444 Label done; | 1470 Label done; |
1445 | 1471 |
1446 // Compute the hash code from the untagged key. This must be kept in sync | 1472 GetNumberHash(t0, t1); |
1447 // with ComputeIntegerHash in utils.h. | |
1448 // | |
1449 // hash = ~hash + (hash << 15); | |
1450 mvn(t1, Operand(t0)); | |
1451 add(t0, t1, Operand(t0, LSL, 15)); | |
1452 // hash = hash ^ (hash >> 12); | |
1453 eor(t0, t0, Operand(t0, LSR, 12)); | |
1454 // hash = hash + (hash << 2); | |
1455 add(t0, t0, Operand(t0, LSL, 2)); | |
1456 // hash = hash ^ (hash >> 4); | |
1457 eor(t0, t0, Operand(t0, LSR, 4)); | |
1458 // hash = hash * 2057; | |
1459 mov(t1, Operand(2057)); | |
1460 mul(t0, t0, t1); | |
1461 // hash = hash ^ (hash >> 16); | |
1462 eor(t0, t0, Operand(t0, LSR, 16)); | |
1463 | 1473 |
1464 // Compute the capacity mask. | 1474 // Compute the capacity mask. |
1465 ldr(t1, FieldMemOperand(elements, NumberDictionary::kCapacityOffset)); | 1475 ldr(t1, FieldMemOperand(elements, SeededNumberDictionary::kCapacityOffset)); |
1466 mov(t1, Operand(t1, ASR, kSmiTagSize)); // convert smi to int | 1476 mov(t1, Operand(t1, ASR, kSmiTagSize)); // convert smi to int |
1467 sub(t1, t1, Operand(1)); | 1477 sub(t1, t1, Operand(1)); |
1468 | 1478 |
1469 // Generate an unrolled loop that performs a few probes before giving up. | 1479 // Generate an unrolled loop that performs a few probes before giving up. |
1470 static const int kProbes = 4; | 1480 static const int kProbes = 4; |
1471 for (int i = 0; i < kProbes; i++) { | 1481 for (int i = 0; i < kProbes; i++) { |
1472 // Use t2 for index calculations and keep the hash intact in t0. | 1482 // Use t2 for index calculations and keep the hash intact in t0. |
1473 mov(t2, t0); | 1483 mov(t2, t0); |
1474 // Compute the masked index: (hash + i + i * i) & mask. | 1484 // Compute the masked index: (hash + i + i * i) & mask. |
1475 if (i > 0) { | 1485 if (i > 0) { |
1476 add(t2, t2, Operand(NumberDictionary::GetProbeOffset(i))); | 1486 add(t2, t2, Operand(SeededNumberDictionary::GetProbeOffset(i))); |
1477 } | 1487 } |
1478 and_(t2, t2, Operand(t1)); | 1488 and_(t2, t2, Operand(t1)); |
1479 | 1489 |
1480 // Scale the index by multiplying by the element size. | 1490 // Scale the index by multiplying by the element size. |
1481 ASSERT(NumberDictionary::kEntrySize == 3); | 1491 ASSERT(SeededNumberDictionary::kEntrySize == 3); |
1482 add(t2, t2, Operand(t2, LSL, 1)); // t2 = t2 * 3 | 1492 add(t2, t2, Operand(t2, LSL, 1)); // t2 = t2 * 3 |
1483 | 1493 |
1484 // Check if the key is identical to the name. | 1494 // Check if the key is identical to the name. |
1485 add(t2, elements, Operand(t2, LSL, kPointerSizeLog2)); | 1495 add(t2, elements, Operand(t2, LSL, kPointerSizeLog2)); |
1486 ldr(ip, FieldMemOperand(t2, NumberDictionary::kElementsStartOffset)); | 1496 ldr(ip, FieldMemOperand(t2, SeededNumberDictionary::kElementsStartOffset)); |
1487 cmp(key, Operand(ip)); | 1497 cmp(key, Operand(ip)); |
1488 if (i != kProbes - 1) { | 1498 if (i != kProbes - 1) { |
1489 b(eq, &done); | 1499 b(eq, &done); |
1490 } else { | 1500 } else { |
1491 b(ne, miss); | 1501 b(ne, miss); |
1492 } | 1502 } |
1493 } | 1503 } |
1494 | 1504 |
1495 bind(&done); | 1505 bind(&done); |
1496 // Check that the value is a normal property. | 1506 // Check that the value is a normal property. |
1497 // t2: elements + (index * kPointerSize) | 1507 // t2: elements + (index * kPointerSize) |
1498 const int kDetailsOffset = | 1508 const int kDetailsOffset = |
1499 NumberDictionary::kElementsStartOffset + 2 * kPointerSize; | 1509 SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; |
1500 ldr(t1, FieldMemOperand(t2, kDetailsOffset)); | 1510 ldr(t1, FieldMemOperand(t2, kDetailsOffset)); |
1501 tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask))); | 1511 tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask))); |
1502 b(ne, miss); | 1512 b(ne, miss); |
1503 | 1513 |
1504 // Get the value at the masked, scaled index and return. | 1514 // Get the value at the masked, scaled index and return. |
1505 const int kValueOffset = | 1515 const int kValueOffset = |
1506 NumberDictionary::kElementsStartOffset + kPointerSize; | 1516 SeededNumberDictionary::kElementsStartOffset + kPointerSize; |
1507 ldr(result, FieldMemOperand(t2, kValueOffset)); | 1517 ldr(result, FieldMemOperand(t2, kValueOffset)); |
1508 } | 1518 } |
1509 | 1519 |
1510 | 1520 |
1511 void MacroAssembler::AllocateInNewSpace(int object_size, | 1521 void MacroAssembler::AllocateInNewSpace(int object_size, |
1512 Register result, | 1522 Register result, |
1513 Register scratch1, | 1523 Register scratch1, |
1514 Register scratch2, | 1524 Register scratch2, |
1515 Label* gc_required, | 1525 Label* gc_required, |
1516 AllocationFlags flags) { | 1526 AllocationFlags flags) { |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1985 CpuFeatures::Scope scope(VFP3); | 1995 CpuFeatures::Scope scope(VFP3); |
1986 vstr(d0, scratch1, 0); | 1996 vstr(d0, scratch1, 0); |
1987 } else { | 1997 } else { |
1988 str(mantissa_reg, MemOperand(scratch1, 0)); | 1998 str(mantissa_reg, MemOperand(scratch1, 0)); |
1989 str(exponent_reg, MemOperand(scratch1, Register::kSizeInBytes)); | 1999 str(exponent_reg, MemOperand(scratch1, Register::kSizeInBytes)); |
1990 } | 2000 } |
1991 bind(&done); | 2001 bind(&done); |
1992 } | 2002 } |
1993 | 2003 |
1994 | 2004 |
| 2005 void MacroAssembler::CompareMap(Register obj, |
| 2006 Register scratch, |
| 2007 Handle<Map> map, |
| 2008 Label* early_success, |
| 2009 CompareMapMode mode) { |
| 2010 ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); |
| 2011 cmp(scratch, Operand(map)); |
| 2012 if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) { |
| 2013 Map* transitioned_fast_element_map( |
| 2014 map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL)); |
| 2015 ASSERT(transitioned_fast_element_map == NULL || |
| 2016 map->elements_kind() != FAST_ELEMENTS); |
| 2017 if (transitioned_fast_element_map != NULL) { |
| 2018 b(eq, early_success); |
| 2019 cmp(scratch, Operand(Handle<Map>(transitioned_fast_element_map))); |
| 2020 } |
| 2021 |
| 2022 Map* transitioned_double_map( |
| 2023 map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL)); |
| 2024 ASSERT(transitioned_double_map == NULL || |
| 2025 map->elements_kind() == FAST_SMI_ONLY_ELEMENTS); |
| 2026 if (transitioned_double_map != NULL) { |
| 2027 b(eq, early_success); |
| 2028 cmp(scratch, Operand(Handle<Map>(transitioned_double_map))); |
| 2029 } |
| 2030 } |
| 2031 } |
| 2032 |
| 2033 |
1995 void MacroAssembler::CheckMap(Register obj, | 2034 void MacroAssembler::CheckMap(Register obj, |
1996 Register scratch, | 2035 Register scratch, |
1997 Handle<Map> map, | 2036 Handle<Map> map, |
1998 Label* fail, | 2037 Label* fail, |
1999 SmiCheckType smi_check_type) { | 2038 SmiCheckType smi_check_type, |
| 2039 CompareMapMode mode) { |
2000 if (smi_check_type == DO_SMI_CHECK) { | 2040 if (smi_check_type == DO_SMI_CHECK) { |
2001 JumpIfSmi(obj, fail); | 2041 JumpIfSmi(obj, fail); |
2002 } | 2042 } |
2003 ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); | 2043 |
2004 mov(ip, Operand(map)); | 2044 Label success; |
2005 cmp(scratch, ip); | 2045 CompareMap(obj, scratch, map, &success, mode); |
2006 b(ne, fail); | 2046 b(ne, fail); |
| 2047 bind(&success); |
2007 } | 2048 } |
2008 | 2049 |
2009 | 2050 |
2010 void MacroAssembler::CheckMap(Register obj, | 2051 void MacroAssembler::CheckMap(Register obj, |
2011 Register scratch, | 2052 Register scratch, |
2012 Heap::RootListIndex index, | 2053 Heap::RootListIndex index, |
2013 Label* fail, | 2054 Label* fail, |
2014 SmiCheckType smi_check_type) { | 2055 SmiCheckType smi_check_type) { |
2015 if (smi_check_type == DO_SMI_CHECK) { | 2056 if (smi_check_type == DO_SMI_CHECK) { |
2016 JumpIfSmi(obj, fail); | 2057 JumpIfSmi(obj, fail); |
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3453 ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); | 3494 ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); |
3454 | 3495 |
3455 Label done; | 3496 Label done; |
3456 | 3497 |
3457 // Since both black and grey have a 1 in the first position and white does | 3498 // Since both black and grey have a 1 in the first position and white does |
3458 // not have a 1 there we only need to check one bit. | 3499 // not have a 1 there we only need to check one bit. |
3459 ldr(load_scratch, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize)); | 3500 ldr(load_scratch, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize)); |
3460 tst(mask_scratch, load_scratch); | 3501 tst(mask_scratch, load_scratch); |
3461 b(ne, &done); | 3502 b(ne, &done); |
3462 | 3503 |
3463 if (FLAG_debug_code) { | 3504 if (emit_debug_code()) { |
3464 // Check for impossible bit pattern. | 3505 // Check for impossible bit pattern. |
3465 Label ok; | 3506 Label ok; |
3466 // LSL may overflow, making the check conservative. | 3507 // LSL may overflow, making the check conservative. |
3467 tst(load_scratch, Operand(mask_scratch, LSL, 1)); | 3508 tst(load_scratch, Operand(mask_scratch, LSL, 1)); |
3468 b(eq, &ok); | 3509 b(eq, &ok); |
3469 stop("Impossible marking bit pattern"); | 3510 stop("Impossible marking bit pattern"); |
3470 bind(&ok); | 3511 bind(&ok); |
3471 } | 3512 } |
3472 | 3513 |
3473 // Value is white. We check whether it is data that doesn't need scanning. | 3514 // Value is white. We check whether it is data that doesn't need scanning. |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3625 void CodePatcher::EmitCondition(Condition cond) { | 3666 void CodePatcher::EmitCondition(Condition cond) { |
3626 Instr instr = Assembler::instr_at(masm_.pc_); | 3667 Instr instr = Assembler::instr_at(masm_.pc_); |
3627 instr = (instr & ~kCondMask) | cond; | 3668 instr = (instr & ~kCondMask) | cond; |
3628 masm_.emit(instr); | 3669 masm_.emit(instr); |
3629 } | 3670 } |
3630 | 3671 |
3631 | 3672 |
3632 } } // namespace v8::internal | 3673 } } // namespace v8::internal |
3633 | 3674 |
3634 #endif // V8_TARGET_ARCH_ARM | 3675 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |