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

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
« no previous file with comments | « runtime/vm/assembler_ia32.h ('k') | runtime/vm/flow_graph_compiler_ia32.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_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::VerifyHeapWord(const Address& address) {
2209 if (VerifiedMemory::enabled()) {
2210 Register addr_reg = EDX;
2211 Register value = EBX;
2212 // Preserve registers.
2213 pushl(addr_reg);
2214 pushl(value);
2215 leal(addr_reg, address);
2216 // ASSERT(*address == *(address + offset))
2217 movl(value, Address(addr_reg, 0));
2218 cmpl(value, Address(addr_reg, VerifiedMemory::offset()));
2219 Label ok;
2220 j(EQUAL, &ok, Assembler::kNearJump);
2221 Stop("Write barrier verification failed");
2222 Bind(&ok);
2223 popl(value);
2224 popl(addr_reg);
2225 }
2226 }
2227
2228
2202 void Assembler::VerifiedWrite(const Address& dest, Register value) { 2229 void Assembler::VerifiedWrite(const Address& dest, Register value) {
2203 // TODO(koda): Verify previous value. 2230 VerifyHeapWord(dest);
2204 movl(dest, value); 2231 movl(dest, value);
2205 if (VerifiedMemory::enabled()) { 2232 if (VerifiedMemory::enabled()) {
2206 Register temp = (value == EDX) ? ECX : EDX; 2233 Register temp = (value == EDX) ? ECX : EDX;
2207 pushl(temp); 2234 pushl(temp);
2208 leal(temp, dest); 2235 leal(temp, dest);
2209 movl(Address(temp, VerifiedMemory::offset()), value); 2236 movl(Address(temp, VerifiedMemory::offset()), value);
2210 popl(temp); 2237 popl(temp);
2211 } 2238 }
2212 } 2239 }
2213 2240
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2291 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2265 EmitUint8(0xC7); 2292 EmitUint8(0xC7);
2266 EmitOperand(0, dest); 2293 EmitOperand(0, dest);
2267 buffer_.EmitObject(value); 2294 buffer_.EmitObject(value);
2268 } 2295 }
2269 2296
2270 2297
2271 void Assembler::StoreIntoObjectNoBarrier(Register object, 2298 void Assembler::StoreIntoObjectNoBarrier(Register object,
2272 const Address& dest, 2299 const Address& dest,
2273 const Object& value) { 2300 const Object& value) {
2301 VerifyHeapWord(dest);
2274 if (value.IsSmi() || value.InVMHeap()) { 2302 if (value.IsSmi() || value.InVMHeap()) {
2275 // TODO(koda): Verify previous value.
2276 Immediate imm_value(reinterpret_cast<int32_t>(value.raw())); 2303 Immediate imm_value(reinterpret_cast<int32_t>(value.raw()));
2277 movl(dest, imm_value); 2304 movl(dest, imm_value);
2278 if (VerifiedMemory::enabled()) { 2305 if (VerifiedMemory::enabled()) {
2279 Register temp = ECX; 2306 Register temp = ECX;
2280 pushl(temp); 2307 pushl(temp);
2281 leal(temp, dest); 2308 leal(temp, dest);
2282 movl(Address(temp, VerifiedMemory::offset()), imm_value); 2309 movl(Address(temp, VerifiedMemory::offset()), imm_value);
2283 popl(temp); 2310 popl(temp);
2284 } 2311 }
2285 } else { 2312 } else {
(...skipping 16 matching lines...) Expand all
2302 Label done; 2329 Label done;
2303 testl(value, Immediate(kHeapObjectTag)); 2330 testl(value, Immediate(kHeapObjectTag));
2304 j(ZERO, &done); 2331 j(ZERO, &done);
2305 Stop("Smi expected"); 2332 Stop("Smi expected");
2306 Bind(&done); 2333 Bind(&done);
2307 #endif // defined(DEBUG) 2334 #endif // defined(DEBUG)
2308 } 2335 }
2309 2336
2310 2337
2311 void Assembler::ZeroSmiField(const Address& dest) { 2338 void Assembler::ZeroSmiField(const Address& dest) {
2339 // TODO(koda): Add VerifySmi once we distinguish initalization.
2340 VerifyHeapWord(dest);
2312 Immediate zero(Smi::RawValue(0)); 2341 Immediate zero(Smi::RawValue(0));
2313 // TODO(koda): Verify previous value.
2314 movl(dest, zero); 2342 movl(dest, zero);
2315 if (VerifiedMemory::enabled()) { 2343 if (VerifiedMemory::enabled()) {
2316 Register temp = ECX; 2344 Register temp = ECX;
2317 pushl(temp); 2345 pushl(temp);
2318 leal(temp, dest); 2346 leal(temp, dest);
2319 movl(Address(temp, VerifiedMemory::offset()), zero); 2347 movl(Address(temp, VerifiedMemory::offset()), zero);
2320 popl(temp); 2348 popl(temp);
2321 } 2349 }
2322 } 2350 }
2323 2351
2324 2352
2325 void Assembler::IncrementSmiField(const Address& dest, int32_t increment) { 2353 void Assembler::IncrementSmiField(const Address& dest, int32_t increment) {
2326 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on 2354 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on
2327 // the length of this instruction sequence. 2355 // the length of this instruction sequence.
2328 // 2356 // TODO(koda): Add VerifySmi once we distinguish initalization.
2329 // TODO(koda): Implement testl for addresses and check that dest is a smi. 2357 VerifyHeapWord(dest);
2330 Immediate inc_imm(Smi::RawValue(increment)); 2358 Immediate inc_imm(Smi::RawValue(increment));
2331 addl(dest, inc_imm); 2359 addl(dest, inc_imm);
2332 if (VerifiedMemory::enabled()) { 2360 if (VerifiedMemory::enabled()) {
2333 Register temp = ECX; 2361 Register temp = ECX;
2334 pushl(temp); 2362 pushl(temp);
2335 leal(temp, dest); 2363 leal(temp, dest);
2336 addl(Address(temp, VerifiedMemory::offset()), inc_imm); 2364 addl(Address(temp, VerifiedMemory::offset()), inc_imm);
2337 popl(temp); 2365 popl(temp);
2338 } 2366 }
2339 } 2367 }
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after
2958 2986
2959 const char* Assembler::FpuRegisterName(FpuRegister reg) { 2987 const char* Assembler::FpuRegisterName(FpuRegister reg) {
2960 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 2988 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
2961 return xmm_reg_names[reg]; 2989 return xmm_reg_names[reg];
2962 } 2990 }
2963 2991
2964 2992
2965 } // namespace dart 2993 } // namespace dart
2966 2994
2967 #endif // defined TARGET_ARCH_IA32 2995 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/assembler_ia32.h ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698