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

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

Issue 711833002: Support verified heap pointer writes on ia32. (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/code_patcher.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" 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"
11 #include "vm/heap.h" 11 #include "vm/heap.h"
12 #include "vm/memory_region.h" 12 #include "vm/memory_region.h"
13 #include "vm/runtime_entry.h" 13 #include "vm/runtime_entry.h"
14 #include "vm/stack_frame.h" 14 #include "vm/stack_frame.h"
15 #include "vm/stub_code.h" 15 #include "vm/stub_code.h"
16 #include "vm/verified_memory.h"
16 17
17 namespace dart { 18 namespace dart {
18 19
19 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); 20 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
20 DECLARE_FLAG(bool, inline_alloc); 21 DECLARE_FLAG(bool, inline_alloc);
21 22
22 23
23 class DirectCallRelocation : public AssemblerFixup { 24 class DirectCallRelocation : public AssemblerFixup {
24 public: 25 public:
25 void Process(const MemoryRegion& region, intptr_t position) { 26 void Process(const MemoryRegion& region, intptr_t position) {
(...skipping 2165 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 // Mask out higher, uninteresting bits which were polluted by dest. 2192 // Mask out higher, uninteresting bits which were polluted by dest.
2192 andl(value, Immediate(kObjectAlignment - 1)); 2193 andl(value, Immediate(kObjectAlignment - 1));
2193 // Compare with the expected bit pattern. 2194 // Compare with the expected bit pattern.
2194 cmpl(value, Immediate( 2195 cmpl(value, Immediate(
2195 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag + 2196 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag +
2196 kOldObjectAlignmentOffset + kHeapObjectTag)); 2197 kOldObjectAlignmentOffset + kHeapObjectTag));
2197 j(NOT_ZERO, no_update, Assembler::kNearJump); 2198 j(NOT_ZERO, no_update, Assembler::kNearJump);
2198 } 2199 }
2199 2200
2200 2201
2202 void Assembler::VerifiedWrite(const Address& dest, Register value) {
2203 // TODO(koda): Verify previous value.
2204 movl(dest, value);
2205 if (VerifiedMemory::enabled()) {
2206 Register temp = (value == EDX) ? ECX : EDX;
2207 pushl(temp);
2208 leal(temp, dest);
2209 movl(Address(temp, VerifiedMemory::offset()), value);
2210 popl(temp);
2211 }
2212 }
2213
2214
2201 // Destroys the value register. 2215 // Destroys the value register.
2202 void Assembler::StoreIntoObject(Register object, 2216 void Assembler::StoreIntoObject(Register object,
2203 const Address& dest, 2217 const Address& dest,
2204 Register value, 2218 Register value,
2205 bool can_value_be_smi) { 2219 bool can_value_be_smi) {
2206 ASSERT(object != value); 2220 ASSERT(object != value);
2207 movl(dest, value); 2221 VerifiedWrite(dest, value);
2208 Label done; 2222 Label done;
2209 if (can_value_be_smi) { 2223 if (can_value_be_smi) {
2210 StoreIntoObjectFilter(object, value, &done); 2224 StoreIntoObjectFilter(object, value, &done);
2211 } else { 2225 } else {
2212 StoreIntoObjectFilterNoSmi(object, value, &done); 2226 StoreIntoObjectFilterNoSmi(object, value, &done);
2213 } 2227 }
2214 // A store buffer update is required. 2228 // A store buffer update is required.
2215 if (value != EDX) { 2229 if (value != EDX) {
2216 pushl(EDX); // Preserve EDX. 2230 pushl(EDX); // Preserve EDX.
2217 } 2231 }
2218 if (object != EDX) { 2232 if (object != EDX) {
2219 movl(EDX, object); 2233 movl(EDX, object);
2220 } 2234 }
2221 StubCode* stub_code = Isolate::Current()->stub_code(); 2235 StubCode* stub_code = Isolate::Current()->stub_code();
2222 call(&stub_code->UpdateStoreBufferLabel()); 2236 call(&stub_code->UpdateStoreBufferLabel());
2223 if (value != EDX) { 2237 if (value != EDX) {
2224 popl(EDX); // Restore EDX. 2238 popl(EDX); // Restore EDX.
2225 } 2239 }
2226 Bind(&done); 2240 Bind(&done);
2227 } 2241 }
2228 2242
2229 2243
2230 void Assembler::StoreIntoObjectNoBarrier(Register object, 2244 void Assembler::StoreIntoObjectNoBarrier(Register object,
2231 const Address& dest, 2245 const Address& dest,
2232 Register value) { 2246 Register value) {
2233 movl(dest, value); 2247 VerifiedWrite(dest, value);
2234 #if defined(DEBUG) 2248 #if defined(DEBUG)
2235 Label done; 2249 Label done;
2236 pushl(value); 2250 pushl(value);
2237 StoreIntoObjectFilter(object, value, &done); 2251 StoreIntoObjectFilter(object, value, &done);
2238 Stop("Store buffer update is required"); 2252 Stop("Store buffer update is required");
2239 Bind(&done); 2253 Bind(&done);
2240 popl(value); 2254 popl(value);
2241 #endif // defined(DEBUG) 2255 #endif // defined(DEBUG)
2242 // No store buffer update. 2256 // No store buffer update.
2243 } 2257 }
2244 2258
2245 2259
2260 void Assembler::UnverifiedStoreOldObject(const Address& dest,
2261 const Object& value) {
2262 ASSERT(value.IsOld());
2263 ASSERT(!value.InVMHeap());
2264 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2265 EmitUint8(0xC7);
2266 EmitOperand(0, dest);
2267 buffer_.EmitObject(value);
2268 }
2269
2270
2246 void Assembler::StoreIntoObjectNoBarrier(Register object, 2271 void Assembler::StoreIntoObjectNoBarrier(Register object,
2247 const Address& dest, 2272 const Address& dest,
2248 const Object& value) { 2273 const Object& value) {
2249 if (value.IsSmi() || value.InVMHeap()) { 2274 if (value.IsSmi() || value.InVMHeap()) {
2250 movl(dest, Immediate(reinterpret_cast<int32_t>(value.raw()))); 2275 // TODO(koda): Verify previous value.
2276 Immediate imm_value(reinterpret_cast<int32_t>(value.raw()));
2277 movl(dest, imm_value);
2278 if (VerifiedMemory::enabled()) {
2279 Register temp = ECX;
2280 pushl(temp);
2281 leal(temp, dest);
2282 movl(Address(temp, VerifiedMemory::offset()), imm_value);
2283 popl(temp);
2284 }
2251 } else { 2285 } else {
2252 ASSERT(value.IsOld()); 2286 UnverifiedStoreOldObject(dest, value);
2253 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2287 if (VerifiedMemory::enabled()) {
2254 EmitUint8(0xC7); 2288 Register temp = EDX;
2255 EmitOperand(0, dest); 2289 pushl(temp);
2256 buffer_.EmitObject(value); 2290 leal(temp, dest);
2291 UnverifiedStoreOldObject(Address(temp, VerifiedMemory::offset()), value);
2292 popl(temp);
2293 }
2257 } 2294 }
2258 // No store buffer update. 2295 // No store buffer update.
2259 } 2296 }
2260 2297
2261 2298
2262 void Assembler::StoreIntoSmiField(const Address& dest, Register value) { 2299 void Assembler::StoreIntoSmiField(const Address& dest, Register value) {
2263 movl(dest, value); 2300 VerifiedWrite(dest, value);
2264 #if defined(DEBUG) 2301 #if defined(DEBUG)
2265 Label done; 2302 Label done;
2266 testl(value, Immediate(kHeapObjectTag)); 2303 testl(value, Immediate(kHeapObjectTag));
2267 j(ZERO, &done); 2304 j(ZERO, &done);
2268 Stop("Smi expected"); 2305 Stop("Smi expected");
2269 Bind(&done); 2306 Bind(&done);
2270 #endif // defined(DEBUG) 2307 #endif // defined(DEBUG)
2271 } 2308 }
2272 2309
2273 2310
2311 void Assembler::ZeroSmiField(const Address& dest) {
2312 Immediate zero(Smi::RawValue(0));
Ivan Posva 2014/11/12 21:22:49 Add TODO
koda 2014/11/12 23:47:30 Done.
2313 movl(dest, zero);
2314 if (VerifiedMemory::enabled()) {
2315 Register temp = ECX;
2316 pushl(temp);
2317 leal(temp, dest);
2318 movl(Address(temp, VerifiedMemory::offset()), zero);
2319 popl(temp);
2320 }
2321 }
2322
2323
2274 void Assembler::IncrementSmiField(const Address& dest, int32_t increment) { 2324 void Assembler::IncrementSmiField(const Address& dest, int32_t increment) {
2325 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on
2326 // the length of this instruction sequence.
2327 //
2275 // TODO(koda): Implement testl for addresses and check that dest is a smi. 2328 // TODO(koda): Implement testl for addresses and check that dest is a smi.
2276 addl(dest, Immediate(Smi::RawValue(increment))); 2329 Immediate inc_imm(Smi::RawValue(increment));
2330 addl(dest, inc_imm);
2331 if (VerifiedMemory::enabled()) {
2332 Register temp = ECX;
2333 pushl(temp);
2334 leal(temp, dest);
2335 addl(Address(temp, VerifiedMemory::offset()), inc_imm);
2336 popl(temp);
2337 }
2277 } 2338 }
2278 2339
2279 2340
2280 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) { 2341 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
2281 // TODO(5410843): Need to have a code constants table. 2342 // TODO(5410843): Need to have a code constants table.
2282 int64_t constant = bit_cast<int64_t, double>(value); 2343 int64_t constant = bit_cast<int64_t, double>(value);
2283 pushl(Immediate(Utils::High32Bits(constant))); 2344 pushl(Immediate(Utils::High32Bits(constant)));
2284 pushl(Immediate(Utils::Low32Bits(constant))); 2345 pushl(Immediate(Utils::Low32Bits(constant)));
2285 movsd(dst, Address(ESP, 0)); 2346 movsd(dst, Address(ESP, 0));
2286 addl(ESP, Immediate(2 * kWordSize)); 2347 addl(ESP, Immediate(2 * kWordSize));
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
2896 2957
2897 const char* Assembler::FpuRegisterName(FpuRegister reg) { 2958 const char* Assembler::FpuRegisterName(FpuRegister reg) {
2898 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 2959 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
2899 return xmm_reg_names[reg]; 2960 return xmm_reg_names[reg];
2900 } 2961 }
2901 2962
2902 2963
2903 } // namespace dart 2964 } // namespace dart
2904 2965
2905 #endif // defined TARGET_ARCH_IA32 2966 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/assembler_ia32.h ('k') | runtime/vm/code_patcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698