| 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/heap.h" | 10 #include "vm/heap.h" |
| 11 #include "vm/heap_trace.h" | |
| 12 #include "vm/memory_region.h" | 11 #include "vm/memory_region.h" |
| 13 #include "vm/runtime_entry.h" | 12 #include "vm/runtime_entry.h" |
| 14 #include "vm/stub_code.h" | 13 #include "vm/stub_code.h" |
| 15 | 14 |
| 16 namespace dart { | 15 namespace dart { |
| 17 | 16 |
| 18 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 17 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| 19 DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available"); | 18 DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available"); |
| 20 DECLARE_FLAG(bool, inline_alloc); | 19 DECLARE_FLAG(bool, inline_alloc); |
| 21 | 20 |
| (...skipping 1882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1904 j(NOT_ZERO, no_update, Assembler::kNearJump); | 1903 j(NOT_ZERO, no_update, Assembler::kNearJump); |
| 1905 } | 1904 } |
| 1906 | 1905 |
| 1907 | 1906 |
| 1908 // Destroys the value register. | 1907 // Destroys the value register. |
| 1909 void Assembler::StoreIntoObject(Register object, | 1908 void Assembler::StoreIntoObject(Register object, |
| 1910 const Address& dest, | 1909 const Address& dest, |
| 1911 Register value, | 1910 Register value, |
| 1912 bool can_value_be_smi) { | 1911 bool can_value_be_smi) { |
| 1913 ASSERT(object != value); | 1912 ASSERT(object != value); |
| 1914 TraceStoreIntoObject(object, dest, value); | |
| 1915 movl(dest, value); | 1913 movl(dest, value); |
| 1916 Label done; | 1914 Label done; |
| 1917 if (can_value_be_smi) { | 1915 if (can_value_be_smi) { |
| 1918 StoreIntoObjectFilter(object, value, &done); | 1916 StoreIntoObjectFilter(object, value, &done); |
| 1919 } else { | 1917 } else { |
| 1920 StoreIntoObjectFilterNoSmi(object, value, &done); | 1918 StoreIntoObjectFilterNoSmi(object, value, &done); |
| 1921 } | 1919 } |
| 1922 // A store buffer update is required. | 1920 // A store buffer update is required. |
| 1923 if (value != EAX) pushl(EAX); // Preserve EAX. | 1921 if (value != EAX) pushl(EAX); // Preserve EAX. |
| 1924 if (object != EAX) { | 1922 if (object != EAX) { |
| 1925 movl(EAX, object); | 1923 movl(EAX, object); |
| 1926 } | 1924 } |
| 1927 call(&StubCode::UpdateStoreBufferLabel()); | 1925 call(&StubCode::UpdateStoreBufferLabel()); |
| 1928 if (value != EAX) popl(EAX); // Restore EAX. | 1926 if (value != EAX) popl(EAX); // Restore EAX. |
| 1929 Bind(&done); | 1927 Bind(&done); |
| 1930 } | 1928 } |
| 1931 | 1929 |
| 1932 | 1930 |
| 1933 void Assembler::StoreIntoObjectNoBarrier(Register object, | 1931 void Assembler::StoreIntoObjectNoBarrier(Register object, |
| 1934 const Address& dest, | 1932 const Address& dest, |
| 1935 Register value) { | 1933 Register value) { |
| 1936 TraceStoreIntoObject(object, dest, value); | |
| 1937 movl(dest, value); | 1934 movl(dest, value); |
| 1938 #if defined(DEBUG) | 1935 #if defined(DEBUG) |
| 1939 Label done; | 1936 Label done; |
| 1940 pushl(value); | 1937 pushl(value); |
| 1941 StoreIntoObjectFilter(object, value, &done); | 1938 StoreIntoObjectFilter(object, value, &done); |
| 1942 Stop("Store buffer update is required"); | 1939 Stop("Store buffer update is required"); |
| 1943 Bind(&done); | 1940 Bind(&done); |
| 1944 popl(value); | 1941 popl(value); |
| 1945 #endif // defined(DEBUG) | 1942 #endif // defined(DEBUG) |
| 1946 // No store buffer update. | 1943 // No store buffer update. |
| 1947 } | 1944 } |
| 1948 | 1945 |
| 1949 | 1946 |
| 1950 void Assembler::StoreIntoObjectNoBarrier(Register object, | 1947 void Assembler::StoreIntoObjectNoBarrier(Register object, |
| 1951 const Address& dest, | 1948 const Address& dest, |
| 1952 const Object& value) { | 1949 const Object& value) { |
| 1953 if (value.IsSmi() || value.InVMHeap()) { | 1950 if (value.IsSmi() || value.InVMHeap()) { |
| 1954 movl(dest, Immediate(reinterpret_cast<int32_t>(value.raw()))); | 1951 movl(dest, Immediate(reinterpret_cast<int32_t>(value.raw()))); |
| 1955 } else { | 1952 } else { |
| 1956 // No heap trace for an old object store. | |
| 1957 ASSERT(value.IsOld()); | 1953 ASSERT(value.IsOld()); |
| 1958 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1954 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1959 EmitUint8(0xC7); | 1955 EmitUint8(0xC7); |
| 1960 EmitOperand(0, dest); | 1956 EmitOperand(0, dest); |
| 1961 buffer_.EmitObject(value); | 1957 buffer_.EmitObject(value); |
| 1962 } | 1958 } |
| 1963 // No store buffer update. | 1959 // No store buffer update. |
| 1964 } | 1960 } |
| 1965 | 1961 |
| 1966 | 1962 |
| 1967 void Assembler::TraceStoreIntoObject(Register object, | |
| 1968 const Address& dest, | |
| 1969 Register value) { | |
| 1970 if (HeapTrace::is_enabled()) { | |
| 1971 pushal(); | |
| 1972 EnterCallRuntimeFrame(3 * kWordSize); | |
| 1973 movl(Address(ESP, 0 * kWordSize), object); | |
| 1974 leal(EAX, dest); | |
| 1975 movl(Address(ESP, 1 * kWordSize), EAX); | |
| 1976 movl(Address(ESP, 2 * kWordSize), value); | |
| 1977 CallRuntime(kHeapTraceStoreRuntimeEntry); | |
| 1978 LeaveCallRuntimeFrame(); | |
| 1979 popal(); | |
| 1980 } | |
| 1981 } | |
| 1982 | |
| 1983 | |
| 1984 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) { | 1963 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) { |
| 1985 // TODO(5410843): Need to have a code constants table. | 1964 // TODO(5410843): Need to have a code constants table. |
| 1986 int64_t constant = bit_cast<int64_t, double>(value); | 1965 int64_t constant = bit_cast<int64_t, double>(value); |
| 1987 pushl(Immediate(Utils::High32Bits(constant))); | 1966 pushl(Immediate(Utils::High32Bits(constant))); |
| 1988 pushl(Immediate(Utils::Low32Bits(constant))); | 1967 pushl(Immediate(Utils::Low32Bits(constant))); |
| 1989 movsd(dst, Address(ESP, 0)); | 1968 movsd(dst, Address(ESP, 0)); |
| 1990 addl(ESP, Immediate(2 * kWordSize)); | 1969 addl(ESP, Immediate(2 * kWordSize)); |
| 1991 } | 1970 } |
| 1992 | 1971 |
| 1993 | 1972 |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2377 | 2356 |
| 2378 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 2357 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 2379 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 2358 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 2380 return xmm_reg_names[reg]; | 2359 return xmm_reg_names[reg]; |
| 2381 } | 2360 } |
| 2382 | 2361 |
| 2383 | 2362 |
| 2384 } // namespace dart | 2363 } // namespace dart |
| 2385 | 2364 |
| 2386 #endif // defined TARGET_ARCH_IA32 | 2365 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |