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

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

Issue 721233002: Write barrier audit: Verify previous value in generated code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 1 month 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
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_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 1927 matching lines...) Expand 10 before | Expand all | Expand 10 after
1938 1938
1939 1939
1940 void Assembler::hlt() { 1940 void Assembler::hlt() {
1941 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1941 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1942 EmitUint8(0xF4); 1942 EmitUint8(0xF4);
1943 } 1943 }
1944 1944
1945 1945
1946 void Assembler::j(Condition condition, Label* label, bool near) { 1946 void Assembler::j(Condition condition, Label* label, bool near) {
1947 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1947 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1948 if (VerifiedMemory::enabled()) {
1949 near = Assembler::kFarJump;
1950 }
1948 if (label->IsBound()) { 1951 if (label->IsBound()) {
1949 static const int kShortSize = 2; 1952 static const int kShortSize = 2;
1950 static const int kLongSize = 6; 1953 static const int kLongSize = 6;
1951 intptr_t offset = label->Position() - buffer_.Size(); 1954 intptr_t offset = label->Position() - buffer_.Size();
1952 ASSERT(offset <= 0); 1955 ASSERT(offset <= 0);
1953 if (Utils::IsInt(8, offset - kShortSize)) { 1956 if (Utils::IsInt(8, offset - kShortSize)) {
1954 EmitUint8(0x70 + condition); 1957 EmitUint8(0x70 + condition);
1955 EmitUint8((offset - kShortSize) & 0xFF); 1958 EmitUint8((offset - kShortSize) & 0xFF);
1956 } else { 1959 } else {
1957 EmitUint8(0x0F); 1960 EmitUint8(0x0F);
(...skipping 22 matching lines...) Expand all
1980 1983
1981 void Assembler::jmp(Register reg) { 1984 void Assembler::jmp(Register reg) {
1982 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1985 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1983 EmitUint8(0xFF); 1986 EmitUint8(0xFF);
1984 EmitRegisterOperand(4, reg); 1987 EmitRegisterOperand(4, reg);
1985 } 1988 }
1986 1989
1987 1990
1988 void Assembler::jmp(Label* label, bool near) { 1991 void Assembler::jmp(Label* label, bool near) {
1989 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1992 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1993 if (VerifiedMemory::enabled()) {
1994 near = Assembler::kFarJump;
1995 }
1990 if (label->IsBound()) { 1996 if (label->IsBound()) {
1991 static const int kShortSize = 2; 1997 static const int kShortSize = 2;
1992 static const int kLongSize = 5; 1998 static const int kLongSize = 5;
1993 intptr_t offset = label->Position() - buffer_.Size(); 1999 intptr_t offset = label->Position() - buffer_.Size();
1994 ASSERT(offset <= 0); 2000 ASSERT(offset <= 0);
1995 if (Utils::IsInt(8, offset - kShortSize)) { 2001 if (Utils::IsInt(8, offset - kShortSize)) {
1996 EmitUint8(0xEB); 2002 EmitUint8(0xEB);
1997 EmitUint8((offset - kShortSize) & 0xFF); 2003 EmitUint8((offset - kShortSize) & 0xFF);
1998 } else { 2004 } else {
1999 EmitUint8(0xE9); 2005 EmitUint8(0xE9);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
2192 // Mask out higher, uninteresting bits which were polluted by dest. 2198 // Mask out higher, uninteresting bits which were polluted by dest.
2193 andl(value, Immediate(kObjectAlignment - 1)); 2199 andl(value, Immediate(kObjectAlignment - 1));
2194 // Compare with the expected bit pattern. 2200 // Compare with the expected bit pattern.
2195 cmpl(value, Immediate( 2201 cmpl(value, Immediate(
2196 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag + 2202 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag +
2197 kOldObjectAlignmentOffset + kHeapObjectTag)); 2203 kOldObjectAlignmentOffset + kHeapObjectTag));
2198 j(NOT_ZERO, no_update, Assembler::kNearJump); 2204 j(NOT_ZERO, no_update, Assembler::kNearJump);
2199 } 2205 }
2200 2206
2201 2207
2208 void Assembler::Verify(const Address& dest) {
Ivan Posva 2014/11/14 22:09:11 Verify is a bit too generic a name for this functi
koda 2014/11/17 16:17:11 Renamed to VerifyHeapWord.
2209 if (VerifiedMemory::enabled()) {
2210 Register dest_addr = EDX;
2211 Register old_value = EBX;
2212 pushl(dest_addr);
Ivan Posva 2014/11/14 22:09:11 Some comments explaining what is going on here wou
koda 2014/11/17 16:17:11 Done. Also improved naming of vars/params.
2213 pushl(old_value);
2214 leal(dest_addr, dest);
2215 movl(old_value, Address(dest_addr, 0));
2216 cmpl(old_value, Address(dest_addr, VerifiedMemory::offset()));
2217 Label ok;
2218 j(EQUAL, &ok, Assembler::kNearJump);
2219 Stop("Write barrier verification failed");
2220 Bind(&ok);
2221 popl(old_value);
2222 popl(dest_addr);
2223 }
2224 }
2225
2226
2202 void Assembler::VerifiedWrite(const Address& dest, Register value) { 2227 void Assembler::VerifiedWrite(const Address& dest, Register value) {
2203 // TODO(koda): Verify previous value. 2228 Verify(dest);
2204 movl(dest, value); 2229 movl(dest, value);
2205 if (VerifiedMemory::enabled()) { 2230 if (VerifiedMemory::enabled()) {
2206 Register temp = (value == EDX) ? ECX : EDX; 2231 Register temp = (value == EDX) ? ECX : EDX;
2207 pushl(temp); 2232 pushl(temp);
2208 leal(temp, dest); 2233 leal(temp, dest);
2209 movl(Address(temp, VerifiedMemory::offset()), value); 2234 movl(Address(temp, VerifiedMemory::offset()), value);
2210 popl(temp); 2235 popl(temp);
2211 } 2236 }
2212 } 2237 }
2213 2238
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2289 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2265 EmitUint8(0xC7); 2290 EmitUint8(0xC7);
2266 EmitOperand(0, dest); 2291 EmitOperand(0, dest);
2267 buffer_.EmitObject(value); 2292 buffer_.EmitObject(value);
2268 } 2293 }
2269 2294
2270 2295
2271 void Assembler::StoreIntoObjectNoBarrier(Register object, 2296 void Assembler::StoreIntoObjectNoBarrier(Register object,
2272 const Address& dest, 2297 const Address& dest,
2273 const Object& value) { 2298 const Object& value) {
2299 Verify(dest);
2274 if (value.IsSmi() || value.InVMHeap()) { 2300 if (value.IsSmi() || value.InVMHeap()) {
2275 // TODO(koda): Verify previous value.
2276 Immediate imm_value(reinterpret_cast<int32_t>(value.raw())); 2301 Immediate imm_value(reinterpret_cast<int32_t>(value.raw()));
2277 movl(dest, imm_value); 2302 movl(dest, imm_value);
2278 if (VerifiedMemory::enabled()) { 2303 if (VerifiedMemory::enabled()) {
2279 Register temp = ECX; 2304 Register temp = ECX;
2280 pushl(temp); 2305 pushl(temp);
2281 leal(temp, dest); 2306 leal(temp, dest);
2282 movl(Address(temp, VerifiedMemory::offset()), imm_value); 2307 movl(Address(temp, VerifiedMemory::offset()), imm_value);
2283 popl(temp); 2308 popl(temp);
2284 } 2309 }
2285 } else { 2310 } else {
(...skipping 16 matching lines...) Expand all
2302 Label done; 2327 Label done;
2303 testl(value, Immediate(kHeapObjectTag)); 2328 testl(value, Immediate(kHeapObjectTag));
2304 j(ZERO, &done); 2329 j(ZERO, &done);
2305 Stop("Smi expected"); 2330 Stop("Smi expected");
2306 Bind(&done); 2331 Bind(&done);
2307 #endif // defined(DEBUG) 2332 #endif // defined(DEBUG)
2308 } 2333 }
2309 2334
2310 2335
2311 void Assembler::ZeroSmiField(const Address& dest) { 2336 void Assembler::ZeroSmiField(const Address& dest) {
2337 Verify(dest); // TODO(koda): Add VerifySmi once we distinguish initalization.
2312 Immediate zero(Smi::RawValue(0)); 2338 Immediate zero(Smi::RawValue(0));
2313 // TODO(koda): Verify previous value.
2314 movl(dest, zero); 2339 movl(dest, zero);
2315 if (VerifiedMemory::enabled()) { 2340 if (VerifiedMemory::enabled()) {
2316 Register temp = ECX; 2341 Register temp = ECX;
2317 pushl(temp); 2342 pushl(temp);
2318 leal(temp, dest); 2343 leal(temp, dest);
2319 movl(Address(temp, VerifiedMemory::offset()), zero); 2344 movl(Address(temp, VerifiedMemory::offset()), zero);
2320 popl(temp); 2345 popl(temp);
2321 } 2346 }
2322 } 2347 }
2323 2348
2324 2349
2325 void Assembler::IncrementSmiField(const Address& dest, int32_t increment) { 2350 void Assembler::IncrementSmiField(const Address& dest, int32_t increment) {
2326 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on 2351 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on
2327 // the length of this instruction sequence. 2352 // the length of this instruction sequence.
2328 // 2353 Verify(dest); // TODO(koda): Add VerifySmi once we distinguish initalization.
2329 // TODO(koda): Implement testl for addresses and check that dest is a smi.
2330 Immediate inc_imm(Smi::RawValue(increment)); 2354 Immediate inc_imm(Smi::RawValue(increment));
2331 addl(dest, inc_imm); 2355 addl(dest, inc_imm);
2332 if (VerifiedMemory::enabled()) { 2356 if (VerifiedMemory::enabled()) {
2333 Register temp = ECX; 2357 Register temp = ECX;
2334 pushl(temp); 2358 pushl(temp);
2335 leal(temp, dest); 2359 leal(temp, dest);
2336 addl(Address(temp, VerifiedMemory::offset()), inc_imm); 2360 addl(Address(temp, VerifiedMemory::offset()), inc_imm);
2337 popl(temp); 2361 popl(temp);
2338 } 2362 }
2339 } 2363 }
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after
2958 2982
2959 const char* Assembler::FpuRegisterName(FpuRegister reg) { 2983 const char* Assembler::FpuRegisterName(FpuRegister reg) {
2960 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 2984 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
2961 return xmm_reg_names[reg]; 2985 return xmm_reg_names[reg];
2962 } 2986 }
2963 2987
2964 2988
2965 } // namespace dart 2989 } // namespace dart
2966 2990
2967 #endif // defined TARGET_ARCH_IA32 2991 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698