| 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" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1933 | 1933 |
| 1934 compiler->GenerateInstanceOf(token_pos(), | 1934 compiler->GenerateInstanceOf(token_pos(), |
| 1935 deopt_id(), | 1935 deopt_id(), |
| 1936 type(), | 1936 type(), |
| 1937 negate_result(), | 1937 negate_result(), |
| 1938 locs()); | 1938 locs()); |
| 1939 ASSERT(locs()->out(0).reg() == RAX); | 1939 ASSERT(locs()->out(0).reg() == RAX); |
| 1940 } | 1940 } |
| 1941 | 1941 |
| 1942 | 1942 |
| 1943 // TODO(srdjan): In case of constant inputs make CreateArray kNoCall and |
| 1944 // use slow path stub. |
| 1943 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { | 1945 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { |
| 1944 const intptr_t kNumInputs = 2; | 1946 const intptr_t kNumInputs = 2; |
| 1945 const intptr_t kNumTemps = 0; | 1947 const intptr_t kNumTemps = 0; |
| 1946 LocationSummary* locs = | 1948 LocationSummary* locs = |
| 1947 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1949 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1948 locs->set_in(0, Location::RegisterLocation(RBX)); | 1950 locs->set_in(0, Location::RegisterLocation(RBX)); |
| 1949 locs->set_in(1, Location::RegisterLocation(R10)); | 1951 locs->set_in(1, Location::RegisterLocation(R10)); |
| 1950 locs->set_out(0, Location::RegisterLocation(RAX)); | 1952 locs->set_out(0, Location::RegisterLocation(RAX)); |
| 1951 return locs; | 1953 return locs; |
| 1952 } | 1954 } |
| 1953 | 1955 |
| 1954 | 1956 |
| 1957 // Inlines array allocation for known constant values. |
| 1958 static void InlineArrayAllocation(FlowGraphCompiler* compiler, |
| 1959 intptr_t num_elements, |
| 1960 Label* slow_path, |
| 1961 Label* done) { |
| 1962 const Register kLengthReg = R10; |
| 1963 const Register kElemTypeReg = RBX; |
| 1964 const intptr_t kArraySize = Array::InstanceSize(num_elements); |
| 1965 |
| 1966 Isolate* isolate = Isolate::Current(); |
| 1967 Heap* heap = isolate->heap(); |
| 1968 |
| 1969 __ movq(RAX, Immediate(heap->TopAddress())); |
| 1970 __ movq(RAX, Address(RAX, 0)); |
| 1971 __ movq(RCX, RAX); |
| 1972 |
| 1973 __ addq(RCX, Immediate(kArraySize)); |
| 1974 __ j(CARRY, slow_path); |
| 1975 |
| 1976 // Check if the allocation fits into the remaining space. |
| 1977 // RAX: potential new object start. |
| 1978 // RCX: potential next object start. |
| 1979 __ movq(R13, Immediate(heap->EndAddress())); |
| 1980 __ cmpq(RCX, Address(R13, 0)); |
| 1981 __ j(ABOVE_EQUAL, slow_path); |
| 1982 |
| 1983 // Successfully allocated the object(s), now update top to point to |
| 1984 // next object start and initialize the object. |
| 1985 __ movq(R13, Immediate(heap->TopAddress())); |
| 1986 __ movq(Address(R13, 0), RCX); |
| 1987 __ addq(RAX, Immediate(kHeapObjectTag)); |
| 1988 __ movq(R13, Immediate(kArraySize)); |
| 1989 __ UpdateAllocationStatsWithSize(kArrayCid, R13); |
| 1990 |
| 1991 // Initialize the tags. |
| 1992 // RAX: new object start as a tagged pointer. |
| 1993 { |
| 1994 uword tags = 0; |
| 1995 tags = RawObject::ClassIdTag::update(kArrayCid, tags); |
| 1996 tags = RawObject::SizeTag::update(kArraySize, tags); |
| 1997 __ movq(FieldAddress(RAX, Array::tags_offset()), Immediate(tags)); |
| 1998 } |
| 1999 |
| 2000 // RAX: new object start as a tagged pointer. |
| 2001 // Store the type argument field. |
| 2002 __ StoreIntoObjectNoBarrier(RAX, |
| 2003 FieldAddress(RAX, Array::type_arguments_offset()), |
| 2004 kElemTypeReg); |
| 2005 |
| 2006 // Set the length field. |
| 2007 __ StoreIntoObjectNoBarrier(RAX, |
| 2008 FieldAddress(RAX, Array::length_offset()), |
| 2009 kLengthReg); |
| 2010 |
| 2011 // Initialize all array elements to raw_null. |
| 2012 // RAX: new object start as a tagged pointer. |
| 2013 // RCX: new object end address. |
| 2014 // RDI: iterator which initially points to the start of the variable |
| 2015 // data area to be initialized. |
| 2016 __ LoadObject(R12, Object::null_object(), PP); |
| 2017 __ leaq(RDI, FieldAddress(RAX, sizeof(RawArray))); |
| 2018 Label init_loop; |
| 2019 __ Bind(&init_loop); |
| 2020 __ cmpq(RDI, RCX); |
| 2021 __ j(ABOVE_EQUAL, done, Assembler::kNearJump); |
| 2022 __ movq(Address(RDI, 0), R12); |
| 2023 __ addq(RDI, Immediate(kWordSize)); |
| 2024 __ jmp(&init_loop, Assembler::kNearJump); |
| 2025 } |
| 2026 |
| 2027 |
| 1955 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2028 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1956 // Allocate the array. R10 = length, RBX = element type. | 2029 // Allocate the array. R10 = length, RBX = element type. |
| 1957 ASSERT(locs()->in(0).reg() == RBX); | 2030 const Register kLengthReg = R10; |
| 1958 ASSERT(locs()->in(1).reg() == R10); | 2031 const Register kElemTypeReg = RBX; |
| 2032 const Register kResultReg = RAX; |
| 2033 ASSERT(locs()->in(0).reg() == kElemTypeReg); |
| 2034 ASSERT(locs()->in(1).reg() == kLengthReg); |
| 2035 |
| 2036 Label slow_path, done; |
| 2037 if (num_elements()->BindsToConstant() && |
| 2038 num_elements()->BoundConstant().IsSmi()) { |
| 2039 const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value(); |
| 2040 if ((length >= 0) && (length <= Array::kMaxElements)) { |
| 2041 Label slow_path, done; |
| 2042 InlineArrayAllocation(compiler, length, &slow_path, &done); |
| 2043 __ Bind(&slow_path); |
| 2044 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result. |
| 2045 __ pushq(kLengthReg); |
| 2046 __ pushq(kElemTypeReg); |
| 2047 compiler->GenerateRuntimeCall(token_pos(), |
| 2048 deopt_id(), |
| 2049 kAllocateArrayRuntimeEntry, |
| 2050 2, |
| 2051 locs()); |
| 2052 __ Drop(2); |
| 2053 __ popq(kResultReg); |
| 2054 __ Bind(&done); |
| 2055 return; |
| 2056 } |
| 2057 } |
| 2058 |
| 2059 __ Bind(&slow_path); |
| 1959 compiler->GenerateCall(token_pos(), | 2060 compiler->GenerateCall(token_pos(), |
| 1960 &StubCode::AllocateArrayLabel(), | 2061 &StubCode::AllocateArrayLabel(), |
| 1961 PcDescriptors::kOther, | 2062 PcDescriptors::kOther, |
| 1962 locs()); | 2063 locs()); |
| 1963 ASSERT(locs()->out(0).reg() == RAX); | 2064 __ Bind(&done); |
| 2065 ASSERT(locs()->out(0).reg() == kResultReg); |
| 1964 } | 2066 } |
| 1965 | 2067 |
| 1966 | 2068 |
| 1967 class BoxDoubleSlowPath : public SlowPathCode { | 2069 class BoxDoubleSlowPath : public SlowPathCode { |
| 1968 public: | 2070 public: |
| 1969 explicit BoxDoubleSlowPath(Instruction* instruction) | 2071 explicit BoxDoubleSlowPath(Instruction* instruction) |
| 1970 : instruction_(instruction) { } | 2072 : instruction_(instruction) { } |
| 1971 | 2073 |
| 1972 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2074 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1973 __ Comment("BoxDoubleSlowPath"); | 2075 __ Comment("BoxDoubleSlowPath"); |
| (...skipping 3703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5677 PcDescriptors::kOther, | 5779 PcDescriptors::kOther, |
| 5678 locs()); | 5780 locs()); |
| 5679 __ Drop(ArgumentCount()); // Discard arguments. | 5781 __ Drop(ArgumentCount()); // Discard arguments. |
| 5680 } | 5782 } |
| 5681 | 5783 |
| 5682 } // namespace dart | 5784 } // namespace dart |
| 5683 | 5785 |
| 5684 #undef __ | 5786 #undef __ |
| 5685 | 5787 |
| 5686 #endif // defined TARGET_ARCH_X64 | 5788 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |