OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |