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

Side by Side Diff: runtime/vm/assembler_x64.cc

Issue 12438032: Use shorter write-barrier filtering sequence when value is known to be non-smi. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Ivan's comments Created 7 years, 9 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 | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.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 (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/heap.h" 9 #include "vm/heap.h"
10 #include "vm/memory_region.h" 10 #include "vm/memory_region.h"
(...skipping 1672 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 1683
1684 1684
1685 void Assembler::negq(Register reg) { 1685 void Assembler::negq(Register reg) {
1686 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1686 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1687 EmitRegisterREX(reg, REX_W); 1687 EmitRegisterREX(reg, REX_W);
1688 EmitUint8(0xF7); 1688 EmitUint8(0xF7);
1689 EmitOperand(3, Operand(reg)); 1689 EmitOperand(3, Operand(reg));
1690 } 1690 }
1691 1691
1692 1692
1693 void Assembler::notl(Register reg) {
1694 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1695 EmitRegisterREX(reg, REX_NONE);
1696 EmitUint8(0xF7);
1697 EmitUint8(0xD0 | (reg & 7));
1698 }
1699
1700
1693 void Assembler::notq(Register reg) { 1701 void Assembler::notq(Register reg) {
1694 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1702 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1695 EmitRegisterREX(reg, REX_W); 1703 EmitRegisterREX(reg, REX_W);
1696 EmitUint8(0xF7); 1704 EmitUint8(0xF7);
1697 EmitUint8(0xD0 | (reg & 7)); 1705 EmitUint8(0xD0 | (reg & 7));
1698 } 1706 }
1699 1707
1700 1708
1701 void Assembler::enter(const Immediate& imm) { 1709 void Assembler::enter(const Immediate& imm) {
1702 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1710 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 cmpq(reg, Immediate(reinterpret_cast<int64_t>(object.raw()))); 2009 cmpq(reg, Immediate(reinterpret_cast<int64_t>(object.raw())));
2002 } else { 2010 } else {
2003 ASSERT(reg != TMP); 2011 ASSERT(reg != TMP);
2004 LoadObject(TMP, object); 2012 LoadObject(TMP, object);
2005 cmpq(reg, TMP); 2013 cmpq(reg, TMP);
2006 } 2014 }
2007 } 2015 }
2008 2016
2009 2017
2010 // Destroys the value register. 2018 // Destroys the value register.
2019 void Assembler::StoreIntoObjectFilterNoSmi(Register object,
2020 Register value,
2021 Label* no_update) {
2022 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
2023 (kOldObjectAlignmentOffset == 0), young_alignment);
2024
2025 // Write-barrier triggers if the value is in the new space (has bit set) and
2026 // the object is in the old space (has bit cleared).
2027 // To check that we could compute value & ~object and skip the write barrier
2028 // if the bit is not set. However we can't destroy the object.
2029 // However to preserve the object we compute negated expression
2030 // ~value | object instead and skip the write barrier if the bit is set.
2031 notl(value);
2032 orl(value, object);
2033 testl(value, Immediate(kNewObjectAlignmentOffset));
2034 j(NOT_ZERO, no_update, Assembler::kNearJump);
2035 }
2036
2037
2038 // Destroys the value register.
2011 void Assembler::StoreIntoObjectFilter(Register object, 2039 void Assembler::StoreIntoObjectFilter(Register object,
2012 Register value, 2040 Register value,
2013 Label* no_update) { 2041 Label* no_update) {
2014 // For the value we are only interested in the new/old bit and the tag bit. 2042 // For the value we are only interested in the new/old bit and the tag bit.
2015 andl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag)); 2043 andl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag));
2016 // Shift the tag bit into the carry. 2044 // Shift the tag bit into the carry.
2017 shrl(value, Immediate(1)); 2045 shrl(value, Immediate(1));
2018 // Add the tag bits together, if the value is not a Smi the addition will 2046 // Add the tag bits together, if the value is not a Smi the addition will
2019 // overflow into the next bit, leaving us with a zero low bit. 2047 // overflow into the next bit, leaving us with a zero low bit.
2020 adcl(value, object); 2048 adcl(value, object);
2021 // Mask out higher, uninteresting bits which were polluted by dest. 2049 // Mask out higher, uninteresting bits which were polluted by dest.
2022 andl(value, Immediate(kObjectAlignment - 1)); 2050 andl(value, Immediate(kObjectAlignment - 1));
2023 // Compare with the expected bit pattern. 2051 // Compare with the expected bit pattern.
2024 cmpl(value, Immediate( 2052 cmpl(value, Immediate(
2025 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag + 2053 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag +
2026 kOldObjectAlignmentOffset + kHeapObjectTag)); 2054 kOldObjectAlignmentOffset + kHeapObjectTag));
2027 j(NOT_ZERO, no_update, Assembler::kNearJump); 2055 j(NOT_ZERO, no_update, Assembler::kNearJump);
2028 } 2056 }
2029 2057
2030 2058
2031 void Assembler::StoreIntoObject(Register object, 2059 void Assembler::StoreIntoObject(Register object,
2032 const Address& dest, 2060 const Address& dest,
2033 Register value) { 2061 Register value,
2062 bool can_value_be_smi) {
2034 ASSERT(object != value); 2063 ASSERT(object != value);
2035 movq(dest, value); 2064 movq(dest, value);
2036 Label done; 2065 Label done;
2037 StoreIntoObjectFilter(object, value, &done); 2066 if (can_value_be_smi) {
2067 StoreIntoObjectFilter(object, value, &done);
2068 } else {
2069 StoreIntoObjectFilterNoSmi(object, value, &done);
2070 }
2038 // A store buffer update is required. 2071 // A store buffer update is required.
2039 if (value != RAX) pushq(RAX); 2072 if (value != RAX) pushq(RAX);
2040 leaq(RAX, dest); 2073 leaq(RAX, dest);
2041 call(&StubCode::UpdateStoreBufferLabel()); 2074 call(&StubCode::UpdateStoreBufferLabel());
2042 if (value != RAX) popq(RAX); 2075 if (value != RAX) popq(RAX);
2043 Bind(&done); 2076 Bind(&done);
2044 } 2077 }
2045 2078
2046 2079
2047 void Assembler::StoreIntoObjectNoBarrier(Register object, 2080 void Assembler::StoreIntoObjectNoBarrier(Register object,
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
2461 2494
2462 const char* Assembler::FpuRegisterName(FpuRegister reg) { 2495 const char* Assembler::FpuRegisterName(FpuRegister reg) {
2463 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 2496 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
2464 return xmm_reg_names[reg]; 2497 return xmm_reg_names[reg];
2465 } 2498 }
2466 2499
2467 2500
2468 } // namespace dart 2501 } // namespace dart
2469 2502
2470 #endif // defined TARGET_ARCH_X64 2503 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698