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

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

Issue 20755004: Make sure that ICData always contains valid data (non-null values). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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/flow_graph_optimizer.h ('k') | runtime/vm/object.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/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 if (function.IsNull()) { 126 if (function.IsNull()) {
127 return false; 127 return false;
128 } 128 }
129 // Create new ICData, do not modify the one attached to the instruction 129 // Create new ICData, do not modify the one attached to the instruction
130 // since it is attached to the assembly instruction itself. 130 // since it is attached to the assembly instruction itself.
131 // TODO(srdjan): Prevent modification of ICData object that is 131 // TODO(srdjan): Prevent modification of ICData object that is
132 // referenced in assembly code. 132 // referenced in assembly code.
133 ICData& ic_data = ICData::ZoneHandle(ICData::New( 133 ICData& ic_data = ICData::ZoneHandle(ICData::New(
134 flow_graph_->parsed_function().function(), 134 flow_graph_->parsed_function().function(),
135 call->function_name(), 135 call->function_name(),
136 Object::null_array(), // Dummy argument descriptor. 136 Object::empty_array(), // Dummy argument descriptor.
137 call->deopt_id(), 137 call->deopt_id(),
138 class_ids.length())); 138 class_ids.length()));
139 ic_data.AddReceiverCheck(class_ids[0], function); 139 ic_data.AddReceiverCheck(class_ids[0], function);
140 call->set_ic_data(&ic_data); 140 call->set_ic_data(&ic_data);
141 return true; 141 return true;
142 } 142 }
143 return false; 143 return false;
144 } 144 }
145 145
146 146
147 static const ICData& SpecializeICData(const ICData& ic_data, intptr_t cid) { 147 static const ICData& SpecializeICData(const ICData& ic_data, intptr_t cid) {
148 ASSERT(ic_data.num_args_tested() == 1); 148 ASSERT(ic_data.num_args_tested() == 1);
149 149
150 if ((ic_data.NumberOfChecks() == 1) && 150 if ((ic_data.NumberOfChecks() == 1) &&
151 (ic_data.GetReceiverClassIdAt(0) == cid)) { 151 (ic_data.GetReceiverClassIdAt(0) == cid)) {
152 return ic_data; // Nothing to do 152 return ic_data; // Nothing to do
153 } 153 }
154 154
155 const ICData& new_ic_data = ICData::ZoneHandle(ICData::New( 155 const ICData& new_ic_data = ICData::ZoneHandle(ICData::New(
156 Function::Handle(ic_data.function()), 156 Function::Handle(ic_data.function()),
157 String::Handle(ic_data.target_name()), 157 String::Handle(ic_data.target_name()),
158 Object::null_array(), // Dummy argument descriptor. 158 Object::empty_array(), // Dummy argument descriptor.
159 ic_data.deopt_id(), 159 ic_data.deopt_id(),
160 ic_data.num_args_tested())); 160 ic_data.num_args_tested()));
161 161
162 const Function& function = 162 const Function& function =
163 Function::Handle(ic_data.GetTargetForReceiverClassId(cid)); 163 Function::Handle(ic_data.GetTargetForReceiverClassId(cid));
164 if (!function.IsNull()) { 164 if (!function.IsNull()) {
165 new_ic_data.AddReceiverCheck(cid, function); 165 new_ic_data.AddReceiverCheck(cid, function);
166 } 166 }
167 167
168 return new_ic_data; 168 return new_ic_data;
(...skipping 1736 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 call, class_ids[0], kTypedDataFloat32ArrayCid); 1905 call, class_ids[0], kTypedDataFloat32ArrayCid);
1906 case MethodRecognizer::kByteArrayBaseGetFloat64: 1906 case MethodRecognizer::kByteArrayBaseGetFloat64:
1907 return BuildByteArrayViewLoad( 1907 return BuildByteArrayViewLoad(
1908 call, class_ids[0], kTypedDataFloat64ArrayCid); 1908 call, class_ids[0], kTypedDataFloat64ArrayCid);
1909 case MethodRecognizer::kByteArrayBaseGetFloat32x4: 1909 case MethodRecognizer::kByteArrayBaseGetFloat32x4:
1910 return BuildByteArrayViewLoad( 1910 return BuildByteArrayViewLoad(
1911 call, class_ids[0], kTypedDataFloat32x4ArrayCid); 1911 call, class_ids[0], kTypedDataFloat32x4ArrayCid);
1912 1912
1913 // ByteArray setters. 1913 // ByteArray setters.
1914 case MethodRecognizer::kByteArrayBaseSetInt8: 1914 case MethodRecognizer::kByteArrayBaseSetInt8:
1915 return BuildByteArrayViewStore( 1915 return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid);
1916 call, class_ids[0], kTypedDataInt8ArrayCid);
1917 case MethodRecognizer::kByteArrayBaseSetUint8: 1916 case MethodRecognizer::kByteArrayBaseSetUint8:
1918 return BuildByteArrayViewStore( 1917 return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid);
1919 call, class_ids[0], kTypedDataUint8ArrayCid);
1920 case MethodRecognizer::kByteArrayBaseSetInt16: 1918 case MethodRecognizer::kByteArrayBaseSetInt16:
1921 return BuildByteArrayViewStore( 1919 return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid);
1922 call, class_ids[0], kTypedDataInt16ArrayCid);
1923 case MethodRecognizer::kByteArrayBaseSetUint16: 1920 case MethodRecognizer::kByteArrayBaseSetUint16:
1924 return BuildByteArrayViewStore( 1921 return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid);
1925 call, class_ids[0], kTypedDataUint16ArrayCid);
1926 case MethodRecognizer::kByteArrayBaseSetInt32: 1922 case MethodRecognizer::kByteArrayBaseSetInt32:
1927 return BuildByteArrayViewStore( 1923 return BuildByteArrayViewStore(call, kTypedDataInt32ArrayCid);
1928 call, class_ids[0], kTypedDataInt32ArrayCid);
1929 case MethodRecognizer::kByteArrayBaseSetUint32: 1924 case MethodRecognizer::kByteArrayBaseSetUint32:
1930 return BuildByteArrayViewStore( 1925 return BuildByteArrayViewStore(call, kTypedDataUint32ArrayCid);
1931 call, class_ids[0], kTypedDataUint32ArrayCid);
1932 case MethodRecognizer::kByteArrayBaseSetFloat32: 1926 case MethodRecognizer::kByteArrayBaseSetFloat32:
1933 return BuildByteArrayViewStore( 1927 return BuildByteArrayViewStore(call, kTypedDataFloat32ArrayCid);
1934 call, class_ids[0], kTypedDataFloat32ArrayCid);
1935 case MethodRecognizer::kByteArrayBaseSetFloat64: 1928 case MethodRecognizer::kByteArrayBaseSetFloat64:
1936 return BuildByteArrayViewStore( 1929 return BuildByteArrayViewStore(call, kTypedDataFloat64ArrayCid);
1937 call, class_ids[0], kTypedDataFloat64ArrayCid);
1938 case MethodRecognizer::kByteArrayBaseSetFloat32x4: 1930 case MethodRecognizer::kByteArrayBaseSetFloat32x4:
1939 return BuildByteArrayViewStore( 1931 return BuildByteArrayViewStore(call, kTypedDataFloat32x4ArrayCid);
1940 call, class_ids[0], kTypedDataFloat32x4ArrayCid);
1941 default: 1932 default:
1942 // Unsupported method. 1933 // Unsupported method.
1943 return false; 1934 return false;
1944 } 1935 }
1945 } 1936 }
1946 1937
1947 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { 1938 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
1948 return TryInlineFloat32x4Method(call, recognized_kind); 1939 return TryInlineFloat32x4Method(call, recognized_kind);
1949 } 1940 }
1950 1941
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
2256 LoadIndexedInstr* array_op = new LoadIndexedInstr(new Value(array), 2247 LoadIndexedInstr* array_op = new LoadIndexedInstr(new Value(array),
2257 new Value(byte_index), 2248 new Value(byte_index),
2258 1, // Index scale. 2249 1, // Index scale.
2259 view_cid, 2250 view_cid,
2260 deopt_id); 2251 deopt_id);
2261 ReplaceCall(call, array_op); 2252 ReplaceCall(call, array_op);
2262 return true; 2253 return true;
2263 } 2254 }
2264 2255
2265 2256
2266 bool FlowGraphOptimizer::BuildByteArrayViewStore( 2257 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call,
2267 InstanceCallInstr* call, 2258 intptr_t view_cid) {
2268 intptr_t receiver_cid,
2269 intptr_t view_cid) {
2270 if ((view_cid == kTypedDataFloat32x4ArrayCid) && !ShouldInlineSimd()) { 2259 if ((view_cid == kTypedDataFloat32x4ArrayCid) && !ShouldInlineSimd()) {
2271 return false; 2260 return false;
2272 } 2261 }
2262 ASSERT(call->HasICData());
2263 Function& target = Function::Handle();
2264 GrowableArray<intptr_t> class_ids;
2265 call->ic_data()->GetCheckAt(0, &class_ids, &target);
2266 const intptr_t receiver_cid = class_ids[0];
2267
2273 Definition* array = call->ArgumentAt(0); 2268 Definition* array = call->ArgumentAt(0);
2274 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array); 2269 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array);
2275 ICData& value_check = ICData::ZoneHandle(); 2270 ICData& value_check = ICData::ZoneHandle();
2276 switch (view_cid) { 2271 switch (view_cid) {
2277 case kTypedDataInt8ArrayCid: 2272 case kTypedDataInt8ArrayCid:
2278 case kTypedDataUint8ArrayCid: 2273 case kTypedDataUint8ArrayCid:
2279 case kTypedDataUint8ClampedArrayCid: 2274 case kTypedDataUint8ClampedArrayCid:
2280 case kExternalTypedDataUint8ArrayCid: 2275 case kExternalTypedDataUint8ArrayCid:
2281 case kExternalTypedDataUint8ClampedArrayCid: 2276 case kExternalTypedDataUint8ClampedArrayCid:
2282 case kTypedDataInt16ArrayCid: 2277 case kTypedDataInt16ArrayCid:
2283 case kTypedDataUint16ArrayCid: { 2278 case kTypedDataUint16ArrayCid: {
2284 // Check that value is always smi. 2279 // Check that value is always smi.
2285 value_check = ICData::New(Function::Handle(), 2280 value_check = ICData::New(flow_graph_->parsed_function().function(),
2286 Object::null_string(), 2281 call->function_name(),
2287 Object::null_array(), 2282 Object::empty_array(), // Dummy args. descr.
2288 Isolate::kNoDeoptId, 2283 Isolate::kNoDeoptId,
2289 1); 2284 1);
2290 value_check.AddReceiverCheck(kSmiCid, Function::Handle()); 2285 value_check.AddReceiverCheck(kSmiCid, target);
2291 break; 2286 break;
2292 } 2287 }
2293 case kTypedDataInt32ArrayCid: 2288 case kTypedDataInt32ArrayCid:
2294 case kTypedDataUint32ArrayCid: 2289 case kTypedDataUint32ArrayCid:
2295 // We don't have ICData for the value stored, so we optimistically assume 2290 // We don't have ICData for the value stored, so we optimistically assume
2296 // smis first. If we ever deoptimized here, we require to unbox the value 2291 // smis first. If we ever deoptimized here, we require to unbox the value
2297 // before storing to handle the mint case, too. 2292 // before storing to handle the mint case, too.
2298 if (call->ic_data()->deopt_reason() == kDeoptUnknown) { 2293 if (call->ic_data()->deopt_reason() == kDeoptUnknown) {
2299 value_check = ICData::New(Function::Handle(), 2294 value_check = ICData::New(flow_graph_->parsed_function().function(),
2300 Object::null_string(), 2295 call->function_name(),
2301 Object::null_array(), // Dummy args. descr. 2296 Object::empty_array(), // Dummy args. descr.
2302 Isolate::kNoDeoptId, 2297 Isolate::kNoDeoptId,
2303 1); 2298 1);
2304 value_check.AddReceiverCheck(kSmiCid, Function::Handle()); 2299 value_check.AddReceiverCheck(kSmiCid, target);
2305 } 2300 }
2306 break; 2301 break;
2307 case kTypedDataFloat32ArrayCid: 2302 case kTypedDataFloat32ArrayCid:
2308 case kTypedDataFloat64ArrayCid: { 2303 case kTypedDataFloat64ArrayCid: {
2309 // Check that value is always double. 2304 // Check that value is always double.
2310 value_check = ICData::New(Function::Handle(), 2305 value_check = ICData::New(flow_graph_->parsed_function().function(),
2311 Object::null_string(), 2306 call->function_name(),
2312 Object::null_array(), // Dummy args. descr. 2307 Object::empty_array(), // Dummy args. descr.
2313 Isolate::kNoDeoptId, 2308 Isolate::kNoDeoptId,
2314 1); 2309 1);
2315 value_check.AddReceiverCheck(kDoubleCid, Function::Handle()); 2310 value_check.AddReceiverCheck(kDoubleCid, target);
2316 break; 2311 break;
2317 } 2312 }
2318 case kTypedDataFloat32x4ArrayCid: { 2313 case kTypedDataFloat32x4ArrayCid: {
2319 // Check that value is always Float32x4. 2314 // Check that value is always Float32x4.
2320 value_check = ICData::New(Function::Handle(), 2315 value_check = ICData::New(flow_graph_->parsed_function().function(),
2321 Object::null_string(), 2316 call->function_name(),
2322 Object::null_array(), // Dummy args. descr. 2317 Object::empty_array(), // Dummy args. descr.
2323 Isolate::kNoDeoptId, 2318 Isolate::kNoDeoptId,
2324 1); 2319 1);
2325 value_check.AddReceiverCheck(kFloat32x4Cid, Function::Handle()); 2320 value_check.AddReceiverCheck(kFloat32x4Cid, target);
2326 break; 2321 break;
2327 } 2322 }
2328 default: 2323 default:
2329 // Array cids are already checked in the caller. 2324 // Array cids are already checked in the caller.
2330 UNREACHABLE(); 2325 UNREACHABLE();
2331 } 2326 }
2332 2327
2333 Definition* index = call->ArgumentAt(1); 2328 Definition* index = call->ArgumentAt(1);
2334 Definition* stored_value = call->ArgumentAt(2); 2329 Definition* stored_value = call->ArgumentAt(2);
2335 if (!value_check.IsNull()) { 2330 if (!value_check.IsNull()) {
(...skipping 5007 matching lines...) Expand 10 before | Expand all | Expand 10 after
7343 7338
7344 // Insert materializations at environment uses. 7339 // Insert materializations at environment uses.
7345 const Class& cls = Class::Handle(alloc->constructor().Owner()); 7340 const Class& cls = Class::Handle(alloc->constructor().Owner());
7346 for (intptr_t i = 0; i < exits.length(); i++) { 7341 for (intptr_t i = 0; i < exits.length(); i++) {
7347 CreateMaterializationAt(exits[i], alloc, cls, *fields); 7342 CreateMaterializationAt(exits[i], alloc, cls, *fields);
7348 } 7343 }
7349 } 7344 }
7350 7345
7351 7346
7352 } // namespace dart 7347 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698