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

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

Issue 11956004: Fix vm code base so that it can be built for --arch=simarm (no snapshot yet). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.cc » ('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) 2012, 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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/flow_graph_allocator.h" 9 #include "vm/flow_graph_allocator.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
(...skipping 1883 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 LocationSummary* ConstraintInstr::MakeLocationSummary() const { 1895 LocationSummary* ConstraintInstr::MakeLocationSummary() const {
1896 UNREACHABLE(); 1896 UNREACHABLE();
1897 return NULL; 1897 return NULL;
1898 } 1898 }
1899 1899
1900 1900
1901 void ConstraintInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1901 void ConstraintInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1902 UNREACHABLE(); 1902 UNREACHABLE();
1903 } 1903 }
1904 1904
1905 LocationSummary* ThrowInstr::MakeLocationSummary() const {
1906 return new LocationSummary(0, 0, LocationSummary::kCall);
1907 }
1908
1909
1910
1911 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1912 compiler->GenerateCallRuntime(token_pos(),
1913 kThrowRuntimeEntry,
1914 locs());
1915 __ int3();
1916 }
1917
1918
1919 LocationSummary* ReThrowInstr::MakeLocationSummary() const {
1920 return new LocationSummary(0, 0, LocationSummary::kCall);
1921 }
1922
1923
1924 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1925 compiler->GenerateCallRuntime(token_pos(),
1926 kReThrowRuntimeEntry,
1927 locs());
1928 __ int3();
1929 }
1930
1931
1932 LocationSummary* GotoInstr::MakeLocationSummary() const {
1933 return new LocationSummary(0, 0, LocationSummary::kNoCall);
1934 }
1935
1936
1937 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1938 // Add deoptimization descriptor for deoptimizing instructions
1939 // that may be inserted before this instruction.
1940 if (!compiler->is_optimizing()) {
1941 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore,
1942 GetDeoptId(),
1943 0); // No token position.
1944 }
1945
1946 if (HasParallelMove()) {
1947 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
1948 }
1949
1950 // We can fall through if the successor is the next block in the list.
1951 // Otherwise, we need a jump.
1952 if (!compiler->IsNextBlock(successor())) {
1953 __ jmp(compiler->GetBlockLabel(successor()));
1954 }
1955 }
1956
1957
1958 static Condition NegateCondition(Condition condition) {
1959 switch (condition) {
1960 case EQUAL: return NOT_EQUAL;
1961 case NOT_EQUAL: return EQUAL;
1962 case LESS: return GREATER_EQUAL;
1963 case LESS_EQUAL: return GREATER;
1964 case GREATER: return LESS_EQUAL;
1965 case GREATER_EQUAL: return LESS;
1966 case BELOW: return ABOVE_EQUAL;
1967 case BELOW_EQUAL: return ABOVE;
1968 case ABOVE: return BELOW_EQUAL;
1969 case ABOVE_EQUAL: return BELOW;
1970 default:
1971 OS::Print("Error %d\n", condition);
1972 UNIMPLEMENTED();
1973 return EQUAL;
1974 }
1975 }
1976
1977
1978 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler,
1979 bool value) {
1980 if (value && compiler->IsNextBlock(false_successor())) {
1981 __ jmp(compiler->GetBlockLabel(true_successor()));
1982 } else if (!value && compiler->IsNextBlock(true_successor())) {
1983 __ jmp(compiler->GetBlockLabel(false_successor()));
1984 }
1985 }
1986
1987
1988 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler,
1989 Condition true_condition) {
1990 if (compiler->IsNextBlock(false_successor())) {
1991 // If the next block is the false successor we will fall through to it.
1992 __ j(true_condition, compiler->GetBlockLabel(true_successor()));
1993 } else {
1994 // If the next block is the true successor we negate comparison and fall
1995 // through to it.
1996 ASSERT(compiler->IsNextBlock(true_successor()));
1997 Condition false_condition = NegateCondition(true_condition);
1998 __ j(false_condition, compiler->GetBlockLabel(false_successor()));
1999 }
2000 }
2001
2002
2003 LocationSummary* CurrentContextInstr::MakeLocationSummary() const {
2004 return LocationSummary::Make(0,
2005 Location::RequiresRegister(),
2006 LocationSummary::kNoCall);
2007 }
2008
2009
2010 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2011 __ MoveRegister(locs()->out().reg(), CTX);
2012 }
2013
2014 1905
2015 LocationSummary* StoreContextInstr::MakeLocationSummary() const { 1906 LocationSummary* StoreContextInstr::MakeLocationSummary() const {
2016 const intptr_t kNumInputs = 1; 1907 const intptr_t kNumInputs = 1;
2017 const intptr_t kNumTemps = 0; 1908 const intptr_t kNumTemps = 0;
2018 LocationSummary* summary = 1909 LocationSummary* summary =
2019 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1910 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2020 summary->set_in(0, Location::RegisterLocation(CTX)); 1911 summary->set_in(0, Location::RegisterLocation(CTX));
2021 return summary; 1912 return summary;
2022 } 1913 }
2023 1914
2024 1915
2025 void StoreContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1916 void StoreContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2026 // Nothing to do. Context register were loaded by register allocator. 1917 // Nothing to do. Context register were loaded by register allocator.
2027 ASSERT(locs()->in(0).reg() == CTX); 1918 ASSERT(locs()->in(0).reg() == CTX);
2028 } 1919 }
2029 1920
2030 1921
2031 StrictCompareInstr::StrictCompareInstr(Token::Kind kind, 1922 StrictCompareInstr::StrictCompareInstr(Token::Kind kind,
2032 Value* left, 1923 Value* left,
2033 Value* right) 1924 Value* right)
2034 : ComparisonInstr(kind, left, right), 1925 : ComparisonInstr(kind, left, right),
2035 needs_number_check_(FLAG_new_identity_spec) { 1926 needs_number_check_(FLAG_new_identity_spec) {
2036 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); 1927 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT));
2037 } 1928 }
2038 1929
2039 1930
2040 LocationSummary* StrictCompareInstr::MakeLocationSummary() const {
2041 const intptr_t kNumInputs = 2;
2042 const intptr_t kNumTemps = 0;
2043 LocationSummary* locs =
2044 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2045 locs->set_in(0, Location::RegisterOrConstant(left()));
2046 locs->set_in(1, Location::RegisterOrConstant(right()));
2047 locs->set_out(Location::RequiresRegister());
2048 return locs;
2049 }
2050
2051
2052 // Special code for numbers (compare values instead of references.)
2053 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2054 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
2055 Location left = locs()->in(0);
2056 Location right = locs()->in(1);
2057 if (left.IsConstant() && right.IsConstant()) {
2058 // TODO(vegorov): should be eliminated earlier by constant propagation.
2059 const bool result = (kind() == Token::kEQ_STRICT) ?
2060 left.constant().raw() == right.constant().raw() :
2061 left.constant().raw() != right.constant().raw();
2062 __ LoadObject(locs()->out().reg(), result ? Bool::True() : Bool::False());
2063 return;
2064 }
2065 if (left.IsConstant()) {
2066 compiler->EmitEqualityRegConstCompare(right.reg(),
2067 left.constant(),
2068 needs_number_check());
2069 } else if (right.IsConstant()) {
2070 compiler->EmitEqualityRegConstCompare(left.reg(),
2071 right.constant(),
2072 needs_number_check());
2073 } else {
2074 compiler->EmitEqualityRegRegCompare(left.reg(),
2075 right.reg(),
2076 needs_number_check());
2077 }
2078
2079 Register result = locs()->out().reg();
2080 Label load_true, done;
2081 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
2082 __ j(true_condition, &load_true, Assembler::kNearJump);
2083 __ LoadObject(result, Bool::False());
2084 __ jmp(&done, Assembler::kNearJump);
2085 __ Bind(&load_true);
2086 __ LoadObject(result, Bool::True());
2087 __ Bind(&done);
2088 }
2089
2090
2091 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
2092 BranchInstr* branch) {
2093 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
2094 Location left = locs()->in(0);
2095 Location right = locs()->in(1);
2096 if (left.IsConstant() && right.IsConstant()) {
2097 // TODO(vegorov): should be eliminated earlier by constant propagation.
2098 const bool result = (kind() == Token::kEQ_STRICT) ?
2099 left.constant().raw() == right.constant().raw() :
2100 left.constant().raw() != right.constant().raw();
2101 branch->EmitBranchOnValue(compiler, result);
2102 return;
2103 }
2104 if (left.IsConstant()) {
2105 compiler->EmitEqualityRegConstCompare(right.reg(),
2106 left.constant(),
2107 needs_number_check());
2108 } else if (right.IsConstant()) {
2109 compiler->EmitEqualityRegConstCompare(left.reg(),
2110 right.constant(),
2111 needs_number_check());
2112 } else {
2113 compiler->EmitEqualityRegRegCompare(left.reg(),
2114 right.reg(),
2115 needs_number_check());
2116 }
2117
2118 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
2119 branch->EmitBranchOnCondition(compiler, true_condition);
2120 }
2121
2122
2123 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2124 // The arguments to the stub include the closure, as does the arguments
2125 // descriptor.
2126 Register temp_reg = locs()->temp(0).reg();
2127 int argument_count = ArgumentCount();
2128 const Array& arguments_descriptor =
2129 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
2130 argument_names()));
2131 __ LoadObject(temp_reg, arguments_descriptor);
2132 compiler->GenerateDartCall(deopt_id(),
2133 token_pos(),
2134 &StubCode::CallClosureFunctionLabel(),
2135 PcDescriptors::kOther,
2136 locs());
2137 __ Drop(argument_count);
2138 }
2139
2140
2141 LocationSummary* InstanceCallInstr::MakeLocationSummary() const { 1931 LocationSummary* InstanceCallInstr::MakeLocationSummary() const {
2142 return MakeCallSummary(); 1932 return MakeCallSummary();
2143 } 1933 }
2144 1934
2145 1935
2146 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1936 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2147 ICData& call_ic_data = ICData::ZoneHandle(ic_data()->raw()); 1937 ICData& call_ic_data = ICData::ZoneHandle(ic_data()->raw());
2148 if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) { 1938 if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) {
2149 call_ic_data = ICData::New(compiler->parsed_function().function(), 1939 call_ic_data = ICData::New(compiler->parsed_function().function(),
2150 function_name(), 1940 function_name(),
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2218 if (!is_eliminated()) { 2008 if (!is_eliminated()) {
2219 compiler->GenerateAssertAssignable(token_pos(), 2009 compiler->GenerateAssertAssignable(token_pos(),
2220 dst_type(), 2010 dst_type(),
2221 dst_name(), 2011 dst_name(),
2222 locs()); 2012 locs());
2223 } 2013 }
2224 ASSERT(locs()->in(0).reg() == locs()->out().reg()); 2014 ASSERT(locs()->in(0).reg() == locs()->out().reg());
2225 } 2015 }
2226 2016
2227 2017
2228 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
2229 return LocationSummary::Make(1,
2230 Location::RequiresRegister(),
2231 LocationSummary::kNoCall);
2232 }
2233
2234
2235 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2236 Register value = locs()->in(0).reg();
2237 Register result = locs()->out().reg();
2238
2239 Label done;
2240 __ LoadObject(result, Bool::True());
2241 __ CompareRegisters(result, value);
2242 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
2243 __ LoadObject(result, Bool::False());
2244 __ Bind(&done);
2245 }
2246
2247
2248 LocationSummary* ChainContextInstr::MakeLocationSummary() const {
2249 return LocationSummary::Make(1,
2250 Location::NoLocation(),
2251 LocationSummary::kNoCall);
2252 }
2253
2254
2255 void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2256 Register context_value = locs()->in(0).reg();
2257
2258 // Chain the new context in context_value to its parent in CTX.
2259 __ StoreIntoObject(context_value,
2260 FieldAddress(context_value, Context::parent_offset()),
2261 CTX);
2262 // Set new context as current context.
2263 __ MoveRegister(CTX, context_value);
2264 }
2265
2266
2267 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const {
2268 const intptr_t kNumInputs = 2;
2269 const intptr_t kNumTemps = 0;
2270 LocationSummary* locs =
2271 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2272 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
2273 : Location::RequiresRegister());
2274 locs->set_in(1, Location::RequiresRegister());
2275 return locs;
2276 }
2277
2278
2279 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2280 Register value_reg = locs()->in(0).reg();
2281 Register dest_reg = locs()->in(1).reg();
2282
2283 if (value()->NeedsStoreBuffer()) {
2284 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
2285 value_reg);
2286 } else {
2287 __ StoreIntoObjectNoBarrier(
2288 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg);
2289 }
2290 }
2291
2292
2293 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const {
2294 return MakeCallSummary();
2295 }
2296
2297
2298 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2299 const Class& cls = Class::ZoneHandle(constructor().Owner());
2300 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
2301 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
2302 compiler->GenerateCall(token_pos(),
2303 &label,
2304 PcDescriptors::kOther,
2305 locs());
2306 __ Drop(ArgumentCount()); // Discard arguments.
2307 }
2308
2309
2310 LocationSummary* CreateClosureInstr::MakeLocationSummary() const {
2311 return MakeCallSummary();
2312 }
2313
2314
2315 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2316 const Function& closure_function = function();
2317 ASSERT(!closure_function.IsImplicitStaticClosureFunction());
2318 const Code& stub = Code::Handle(
2319 StubCode::GetAllocationStubForClosure(closure_function));
2320 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint());
2321 compiler->GenerateCall(token_pos(),
2322 &label,
2323 PcDescriptors::kOther,
2324 locs());
2325 __ Drop(2); // Discard type arguments and receiver.
2326 }
2327
2328
2329 Environment* Environment::From(const GrowableArray<Definition*>& definitions, 2018 Environment* Environment::From(const GrowableArray<Definition*>& definitions,
2330 intptr_t fixed_parameter_count, 2019 intptr_t fixed_parameter_count,
2331 const Function& function) { 2020 const Function& function) {
2332 Environment* env = 2021 Environment* env =
2333 new Environment(definitions.length(), 2022 new Environment(definitions.length(),
2334 fixed_parameter_count, 2023 fixed_parameter_count,
2335 Isolate::kNoDeoptId, 2024 Isolate::kNoDeoptId,
2336 function, 2025 function,
2337 NULL); 2026 NULL);
2338 for (intptr_t i = 0; i < definitions.length(); ++i) { 2027 for (intptr_t i = 0; i < definitions.length(); ++i) {
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
2998 case kFloat64ArrayCid: 2687 case kFloat64ArrayCid:
2999 case kFloat32ArrayCid: 2688 case kFloat32ArrayCid:
3000 case kExternalUint8ArrayCid: 2689 case kExternalUint8ArrayCid:
3001 return ByteArray::length_offset(); 2690 return ByteArray::length_offset();
3002 default: 2691 default:
3003 UNREACHABLE(); 2692 UNREACHABLE();
3004 return -1; 2693 return -1;
3005 } 2694 }
3006 } 2695 }
3007 2696
3008
3009 #undef __ 2697 #undef __
3010 2698
3011 } // namespace dart 2699 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698