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

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

Issue 836593002: Deletion barrier: Distinguish+verify field initialization in ia32 generated code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 11 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_ia32.h ('k') | runtime/vm/assembler_x64.h » ('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" // NOLINT 5 #include "vm/globals.h" // NOLINT
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 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 EmitUint8(0xA9); 1450 EmitUint8(0xA9);
1451 EmitImmediate(immediate); 1451 EmitImmediate(immediate);
1452 } else { 1452 } else {
1453 EmitUint8(0xF7); 1453 EmitUint8(0xF7);
1454 EmitOperand(0, Operand(reg)); 1454 EmitOperand(0, Operand(reg));
1455 EmitImmediate(immediate); 1455 EmitImmediate(immediate);
1456 } 1456 }
1457 } 1457 }
1458 1458
1459 1459
1460 void Assembler::testb(const Address& address, const Immediate& imm) {
1461 ASSERT(imm.is_int8());
1462 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1463 EmitUint8(0xF6);
1464 EmitOperand(0, address);
1465 EmitUint8(imm.value() & 0xFF);
1466 }
1467
1468
1460 void Assembler::andl(Register dst, Register src) { 1469 void Assembler::andl(Register dst, Register src) {
1461 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1470 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1462 EmitUint8(0x23); 1471 EmitUint8(0x23);
1463 EmitOperand(dst, Operand(src)); 1472 EmitOperand(dst, Operand(src));
1464 } 1473 }
1465 1474
1466 1475
1467 void Assembler::andl(Register dst, const Immediate& imm) { 1476 void Assembler::andl(Register dst, const Immediate& imm) {
1468 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1477 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1469 EmitComplex(4, Operand(dst), imm); 1478 EmitComplex(4, Operand(dst), imm);
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
2205 // Mask out higher, uninteresting bits which were polluted by dest. 2214 // Mask out higher, uninteresting bits which were polluted by dest.
2206 andl(value, Immediate(kObjectAlignment - 1)); 2215 andl(value, Immediate(kObjectAlignment - 1));
2207 // Compare with the expected bit pattern. 2216 // Compare with the expected bit pattern.
2208 cmpl(value, Immediate( 2217 cmpl(value, Immediate(
2209 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag + 2218 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag +
2210 kOldObjectAlignmentOffset + kHeapObjectTag)); 2219 kOldObjectAlignmentOffset + kHeapObjectTag));
2211 j(NOT_ZERO, no_update, Assembler::kNearJump); 2220 j(NOT_ZERO, no_update, Assembler::kNearJump);
2212 } 2221 }
2213 2222
2214 2223
2215 void Assembler::VerifyHeapWord(const Address& address) { 2224 void Assembler::VerifyHeapWord(const Address& address,
2225 FieldContent old_content) {
2226 #if defined(DEBUG)
2227 switch (old_content) {
2228 case kEmptyOrSmiOrNull:
2229 VerifyUninitialized(address);
2230 break;
2231 case kHeapObjectOrSmi:
2232 VerifyObjectOrSmi(address);
2233 break;
2234 case kOnlySmi:
2235 VerifySmi(address);
2236 break;
2237 }
2238 #endif // DEBUG
2216 if (VerifiedMemory::enabled()) { 2239 if (VerifiedMemory::enabled()) {
2217 Register addr_reg = EDX; 2240 Register addr_reg = EDX;
2218 Register value = EBX; 2241 Register value = EBX;
2219 // Preserve registers. 2242 // Preserve registers.
2220 pushl(addr_reg); 2243 pushl(addr_reg);
2221 pushl(value); 2244 pushl(value);
2222 leal(addr_reg, address); 2245 leal(addr_reg, address);
2223 // ASSERT(*address == *(address + offset)) 2246 // ASSERT(*address == *(address + offset))
2224 movl(value, Address(addr_reg, 0)); 2247 movl(value, Address(addr_reg, 0));
2225 cmpl(value, Address(addr_reg, VerifiedMemory::offset())); 2248 cmpl(value, Address(addr_reg, VerifiedMemory::offset()));
2226 Label ok; 2249 Label ok;
2227 j(EQUAL, &ok, Assembler::kNearJump); 2250 j(EQUAL, &ok, Assembler::kNearJump);
2228 Stop("Write barrier verification failed"); 2251 Stop("Write barrier verification failed");
2229 Bind(&ok); 2252 Bind(&ok);
2230 popl(value); 2253 popl(value);
2231 popl(addr_reg); 2254 popl(addr_reg);
2232 } 2255 }
2233 } 2256 }
2234 2257
2235 2258
2236 void Assembler::VerifiedWrite(const Address& dest, Register value) { 2259 void Assembler::VerifiedWrite(const Address& dest,
2237 VerifyHeapWord(dest); 2260 Register value,
2261 FieldContent old_content) {
2262 VerifyHeapWord(dest, old_content);
2238 movl(dest, value); 2263 movl(dest, value);
2239 if (VerifiedMemory::enabled()) { 2264 if (VerifiedMemory::enabled()) {
2240 Register temp = (value == EDX) ? ECX : EDX; 2265 Register temp = (value == EDX) ? ECX : EDX;
2241 pushl(temp); 2266 pushl(temp);
2242 leal(temp, dest); 2267 leal(temp, dest);
2243 movl(Address(temp, VerifiedMemory::offset()), value); 2268 movl(Address(temp, VerifiedMemory::offset()), value);
2244 popl(temp); 2269 popl(temp);
2245 } 2270 }
2246 } 2271 }
2247 2272
2248 2273
2274 #if defined(DEBUG)
2275 void Assembler::VerifyObjectOrSmi(const Address& dest) {
2276 Label ok;
2277 testb(dest, Immediate(kHeapObjectTag));
2278 j(ZERO, &ok, Assembler::kNearJump);
2279 // Non-smi case: Verify object pointer is word-aligned when untagged.
2280 COMPILE_ASSERT(kHeapObjectTag == 1);
2281 testb(dest, Immediate((kWordSize - 1) - kHeapObjectTag));
2282 j(ZERO, &ok, Assembler::kNearJump);
2283 Stop("Expected heap object or Smi");
2284 Bind(&ok);
2285 }
2286
2287
2288 void Assembler::VerifyUninitialized(const Address& dest) {
2289 Label ok;
2290 testb(dest, Immediate(kHeapObjectTag));
2291 j(ZERO, &ok, Assembler::kNearJump);
2292 // Non-smi case: Check for the special zap word or null.
2293 cmpl(dest, Immediate(Heap::kZap32Bits));
2294 j(EQUAL, &ok, Assembler::kNearJump);
2295 cmpl(dest, Immediate(reinterpret_cast<uint32_t>(Object::null())));
2296 j(EQUAL, &ok, Assembler::kNearJump);
2297 Stop("Expected zapped, Smi or null");
2298 Bind(&ok);
2299 }
2300
2301
2302 void Assembler::VerifySmi(const Address& dest, const char* stop_msg) {
2303 Label done;
2304 testb(dest, Immediate(kHeapObjectTag));
2305 j(ZERO, &done, Assembler::kNearJump);
2306 Stop(stop_msg);
2307 Bind(&done);
2308 }
2309 #endif // defined(DEBUG)
2310
2311
2249 // Destroys the value register. 2312 // Destroys the value register.
2250 void Assembler::StoreIntoObject(Register object, 2313 void Assembler::StoreIntoObject(Register object,
2251 const Address& dest, 2314 const Address& dest,
2252 Register value, 2315 Register value,
2253 bool can_value_be_smi) { 2316 bool can_value_be_smi) {
2254 ASSERT(object != value); 2317 ASSERT(object != value);
2255 VerifiedWrite(dest, value); 2318 VerifiedWrite(dest, value, kHeapObjectOrSmi);
2256 Label done; 2319 Label done;
2257 if (can_value_be_smi) { 2320 if (can_value_be_smi) {
2258 StoreIntoObjectFilter(object, value, &done); 2321 StoreIntoObjectFilter(object, value, &done);
2259 } else { 2322 } else {
2260 StoreIntoObjectFilterNoSmi(object, value, &done); 2323 StoreIntoObjectFilterNoSmi(object, value, &done);
2261 } 2324 }
2262 // A store buffer update is required. 2325 // A store buffer update is required.
2263 if (value != EDX) { 2326 if (value != EDX) {
2264 pushl(EDX); // Preserve EDX. 2327 pushl(EDX); // Preserve EDX.
2265 } 2328 }
2266 if (object != EDX) { 2329 if (object != EDX) {
2267 movl(EDX, object); 2330 movl(EDX, object);
2268 } 2331 }
2269 StubCode* stub_code = Isolate::Current()->stub_code(); 2332 StubCode* stub_code = Isolate::Current()->stub_code();
2270 call(&stub_code->UpdateStoreBufferLabel()); 2333 call(&stub_code->UpdateStoreBufferLabel());
2271 if (value != EDX) { 2334 if (value != EDX) {
2272 popl(EDX); // Restore EDX. 2335 popl(EDX); // Restore EDX.
2273 } 2336 }
2274 Bind(&done); 2337 Bind(&done);
2275 } 2338 }
2276 2339
2277 2340
2278 void Assembler::StoreIntoObjectNoBarrier(Register object, 2341 void Assembler::StoreIntoObjectNoBarrier(Register object,
2279 const Address& dest, 2342 const Address& dest,
2280 Register value) { 2343 Register value,
2281 VerifiedWrite(dest, value); 2344 FieldContent old_content) {
2345 VerifiedWrite(dest, value, old_content);
2282 #if defined(DEBUG) 2346 #if defined(DEBUG)
2283 Label done; 2347 Label done;
2284 pushl(value); 2348 pushl(value);
2285 StoreIntoObjectFilter(object, value, &done); 2349 StoreIntoObjectFilter(object, value, &done);
2286 Stop("Store buffer update is required"); 2350 Stop("Store buffer update is required");
2287 Bind(&done); 2351 Bind(&done);
2288 popl(value); 2352 popl(value);
2289 #endif // defined(DEBUG) 2353 #endif // defined(DEBUG)
2290 // No store buffer update. 2354 // No store buffer update.
2291 } 2355 }
2292 2356
2293 2357
2294 void Assembler::UnverifiedStoreOldObject(const Address& dest, 2358 void Assembler::UnverifiedStoreOldObject(const Address& dest,
2295 const Object& value) { 2359 const Object& value) {
2296 ASSERT(value.IsOld()); 2360 ASSERT(value.IsOld());
2297 ASSERT(!value.InVMHeap()); 2361 ASSERT(!value.InVMHeap());
2298 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2362 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2299 EmitUint8(0xC7); 2363 EmitUint8(0xC7);
2300 EmitOperand(0, dest); 2364 EmitOperand(0, dest);
2301 buffer_.EmitObject(value); 2365 buffer_.EmitObject(value);
2302 } 2366 }
2303 2367
2304 2368
2305 void Assembler::StoreIntoObjectNoBarrier(Register object, 2369 void Assembler::StoreIntoObjectNoBarrier(Register object,
2306 const Address& dest, 2370 const Address& dest,
2307 const Object& value) { 2371 const Object& value,
2308 VerifyHeapWord(dest); 2372 FieldContent old_content) {
2373 VerifyHeapWord(dest, old_content);
2309 if (value.IsSmi() || value.InVMHeap()) { 2374 if (value.IsSmi() || value.InVMHeap()) {
2310 Immediate imm_value(reinterpret_cast<int32_t>(value.raw())); 2375 Immediate imm_value(reinterpret_cast<int32_t>(value.raw()));
2311 movl(dest, imm_value); 2376 movl(dest, imm_value);
2312 if (VerifiedMemory::enabled()) { 2377 if (VerifiedMemory::enabled()) {
2313 Register temp = ECX; 2378 Register temp = ECX;
2314 pushl(temp); 2379 pushl(temp);
2315 leal(temp, dest); 2380 leal(temp, dest);
2316 movl(Address(temp, VerifiedMemory::offset()), imm_value); 2381 movl(Address(temp, VerifiedMemory::offset()), imm_value);
2317 popl(temp); 2382 popl(temp);
2318 } 2383 }
2319 } else { 2384 } else {
2320 UnverifiedStoreOldObject(dest, value); 2385 UnverifiedStoreOldObject(dest, value);
2321 if (VerifiedMemory::enabled()) { 2386 if (VerifiedMemory::enabled()) {
2322 Register temp = EDX; 2387 Register temp = EDX;
2323 pushl(temp); 2388 pushl(temp);
2324 leal(temp, dest); 2389 leal(temp, dest);
2325 UnverifiedStoreOldObject(Address(temp, VerifiedMemory::offset()), value); 2390 UnverifiedStoreOldObject(Address(temp, VerifiedMemory::offset()), value);
2326 popl(temp); 2391 popl(temp);
2327 } 2392 }
2328 } 2393 }
2329 // No store buffer update. 2394 // No store buffer update.
2330 } 2395 }
2331 2396
2332 2397
2333 void Assembler::StoreIntoSmiField(const Address& dest, Register value) { 2398 void Assembler::StoreIntoSmiField(const Address& dest, Register value) {
2334 VerifiedWrite(dest, value);
2335 #if defined(DEBUG) 2399 #if defined(DEBUG)
2336 Label done; 2400 Label done;
2337 testl(value, Immediate(kHeapObjectTag)); 2401 testl(value, Immediate(kHeapObjectTag));
2338 j(ZERO, &done); 2402 j(ZERO, &done);
2339 Stop("Smi expected"); 2403 Stop("New value must be Smi.");
2340 Bind(&done); 2404 Bind(&done);
2341 #endif // defined(DEBUG) 2405 #endif // defined(DEBUG)
2406 VerifiedWrite(dest, value, kOnlySmi);
2342 } 2407 }
2343 2408
2344 2409
2345 void Assembler::ZeroSmiField(const Address& dest) { 2410 void Assembler::ZeroInitSmiField(const Address& dest) {
2346 // TODO(koda): Add VerifySmi once we distinguish initalization. 2411 VerifyHeapWord(dest, kEmptyOrSmiOrNull);
2347 VerifyHeapWord(dest);
2348 Immediate zero(Smi::RawValue(0)); 2412 Immediate zero(Smi::RawValue(0));
2349 movl(dest, zero); 2413 movl(dest, zero);
2350 if (VerifiedMemory::enabled()) { 2414 if (VerifiedMemory::enabled()) {
2351 Register temp = ECX; 2415 Register temp = ECX;
2352 pushl(temp); 2416 pushl(temp);
2353 leal(temp, dest); 2417 leal(temp, dest);
2354 movl(Address(temp, VerifiedMemory::offset()), zero); 2418 movl(Address(temp, VerifiedMemory::offset()), zero);
2355 popl(temp); 2419 popl(temp);
2356 } 2420 }
2357 } 2421 }
2358 2422
2359 2423
2360 void Assembler::IncrementSmiField(const Address& dest, int32_t increment) { 2424 void Assembler::IncrementSmiField(const Address& dest, int32_t increment) {
2361 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on 2425 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on
2362 // the length of this instruction sequence. 2426 // the length of this instruction sequence.
2363 // TODO(koda): Add VerifySmi once we distinguish initalization. 2427 VerifyHeapWord(dest, kOnlySmi);
2364 VerifyHeapWord(dest);
2365 Immediate inc_imm(Smi::RawValue(increment)); 2428 Immediate inc_imm(Smi::RawValue(increment));
2366 addl(dest, inc_imm); 2429 addl(dest, inc_imm);
2367 if (VerifiedMemory::enabled()) { 2430 if (VerifiedMemory::enabled()) {
2368 Register temp = ECX; 2431 Register temp = ECX;
2369 pushl(temp); 2432 pushl(temp);
2370 leal(temp, dest); 2433 leal(temp, dest);
2371 addl(Address(temp, VerifiedMemory::offset()), inc_imm); 2434 addl(Address(temp, VerifiedMemory::offset()), inc_imm);
2372 popl(temp); 2435 popl(temp);
2373 } 2436 }
2374 } 2437 }
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
3034 3097
3035 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3098 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3036 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 3099 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
3037 return xmm_reg_names[reg]; 3100 return xmm_reg_names[reg];
3038 } 3101 }
3039 3102
3040 3103
3041 } // namespace dart 3104 } // namespace dart
3042 3105
3043 #endif // defined TARGET_ARCH_IA32 3106 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/assembler_ia32.h ('k') | runtime/vm/assembler_x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698