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

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

Issue 15564004: Refactor the IL for object allocation with type arguments. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/code_descriptors.h" 9 #include "vm/code_descriptors.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 1999 matching lines...) Expand 10 before | Expand all | Expand 10 after
2010 } 2010 }
2011 2011
2012 2012
2013 Value* EffectGraphVisitor::BuildObjectAllocation( 2013 Value* EffectGraphVisitor::BuildObjectAllocation(
2014 ConstructorCallNode* node) { 2014 ConstructorCallNode* node) {
2015 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); 2015 const Class& cls = Class::ZoneHandle(node->constructor().Owner());
2016 const bool requires_type_arguments = cls.HasTypeArguments(); 2016 const bool requires_type_arguments = cls.HasTypeArguments();
2017 2017
2018 // In checked mode, if the type arguments are uninstantiated, they may need to 2018 // In checked mode, if the type arguments are uninstantiated, they may need to
2019 // be checked against declared bounds at run time. 2019 // be checked against declared bounds at run time.
2020 Definition* allocate_comp = NULL; 2020 Definition* allocation = NULL;
2021 if (FLAG_enable_type_checks && 2021 if (FLAG_enable_type_checks &&
2022 requires_type_arguments && 2022 requires_type_arguments &&
2023 !node->type_arguments().IsNull() && 2023 !node->type_arguments().IsNull() &&
2024 !node->type_arguments().IsInstantiated() && 2024 !node->type_arguments().IsInstantiated() &&
2025 node->type_arguments().IsBounded()) { 2025 node->type_arguments().IsBounded()) {
2026 Value* type_arguments = NULL; 2026 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments =
2027 Value* instantiator = NULL; 2027 new ZoneGrowableArray<PushArgumentInstr*>(4);
2028 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); 2028 // Argument 1: Empty argument slot for return value.
2029 Value* null_val = Bind(new ConstantInstr(Object::ZoneHandle()));
2030 allocate_arguments->Add(PushArgument(null_val));
2031 // Argument 2: Class.
2032 Value* cls_val =
2033 Bind(new ConstantInstr(Class::ZoneHandle(node->constructor().Owner())));
2034 allocate_arguments->Add(PushArgument(cls_val));
2035 // Build arguments 3 and 4.
2036 BuildConstructorTypeArguments(node, allocate_arguments);
2029 2037
2030 // The uninstantiated type arguments cannot be verified to be within their 2038 // The uninstantiated type arguments cannot be verified to be within their
2031 // bounds at compile time, so verify them at runtime. 2039 // bounds at compile time, so verify them at runtime.
2032 allocate_comp = new AllocateObjectWithBoundsCheckInstr(node, 2040 allocation = new AllocateObjectWithBoundsCheckInstr(node);
2033 type_arguments,
2034 instantiator);
2035 } else { 2041 } else {
2036 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = 2042 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments =
2037 new ZoneGrowableArray<PushArgumentInstr*>(); 2043 new ZoneGrowableArray<PushArgumentInstr*>();
2038
2039 if (requires_type_arguments) { 2044 if (requires_type_arguments) {
2040 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); 2045 BuildConstructorTypeArguments(node, allocate_arguments);
2041 } 2046 }
2042 2047
2043 allocate_comp = new AllocateObjectInstr(node, allocate_arguments); 2048 allocation = new AllocateObjectInstr(node, allocate_arguments);
2044 } 2049 }
2045 return Bind(allocate_comp); 2050 return Bind(allocation);
2046 } 2051 }
2047 2052
2048 2053
2049 void EffectGraphVisitor::BuildConstructorCall( 2054 void EffectGraphVisitor::BuildConstructorCall(
2050 ConstructorCallNode* node, 2055 ConstructorCallNode* node,
2051 PushArgumentInstr* push_alloc_value) { 2056 PushArgumentInstr* push_alloc_value) {
2052 Value* ctor_arg = Bind( 2057 Value* ctor_arg = Bind(
2053 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); 2058 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))));
2054 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); 2059 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg);
2055 2060
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
2242 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 2247 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
2243 return Bind(new InstantiateTypeArgumentsInstr(token_pos, 2248 return Bind(new InstantiateTypeArgumentsInstr(token_pos,
2244 type_arguments, 2249 type_arguments,
2245 instantiator_class, 2250 instantiator_class,
2246 instantiator_value)); 2251 instantiator_value));
2247 } 2252 }
2248 2253
2249 2254
2250 void EffectGraphVisitor::BuildConstructorTypeArguments( 2255 void EffectGraphVisitor::BuildConstructorTypeArguments(
2251 ConstructorCallNode* node, 2256 ConstructorCallNode* node,
2252 Value** type_arguments,
2253 Value** instantiator,
2254 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { 2257 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) {
2255 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); 2258 const Class& cls = Class::ZoneHandle(node->constructor().Owner());
2256 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); 2259 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory());
2257 if (node->type_arguments().IsNull() || 2260 if (node->type_arguments().IsNull() ||
2258 node->type_arguments().IsInstantiated()) { 2261 node->type_arguments().IsInstantiated()) {
2259 Value* type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); 2262 Value* type_arguments_val = Bind(new ConstantInstr(node->type_arguments()));
2260 if (call_arguments != NULL) { 2263 call_arguments->Add(PushArgument(type_arguments_val));
2261 ASSERT(type_arguments == NULL);
2262 call_arguments->Add(PushArgument(type_arguments_val));
2263 } else {
2264 ASSERT(type_arguments != NULL);
2265 *type_arguments = type_arguments_val;
2266 }
2267 2264
2268 // No instantiator required. 2265 // No instantiator required.
2269 Value* instantiator_val = Bind(new ConstantInstr( 2266 Value* instantiator_val = Bind(new ConstantInstr(
2270 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); 2267 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator))));
2271 if (call_arguments != NULL) { 2268 call_arguments->Add(PushArgument(instantiator_val));
2272 ASSERT(instantiator == NULL);
2273 call_arguments->Add(PushArgument(instantiator_val));
2274 } else {
2275 ASSERT(instantiator != NULL);
2276 *instantiator = instantiator_val;
2277 }
2278 return; 2269 return;
2279 } 2270 }
2271
2280 // The type arguments are uninstantiated. We use expression_temp_var to save 2272 // The type arguments are uninstantiated. We use expression_temp_var to save
2281 // the instantiator type arguments becuase they have two uses. 2273 // the instantiator type arguments because they have two uses.
2282 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); 2274 ASSERT(owner()->parsed_function().expression_temp_var() != NULL);
2283 const LocalVariable& temp = *owner()->parsed_function().expression_temp_var(); 2275 const LocalVariable& temp = *owner()->parsed_function().expression_temp_var();
2284 const Class& instantiator_class = Class::Handle( 2276 const Class& instantiator_class = Class::Handle(
2285 owner()->parsed_function().function().Owner()); 2277 owner()->parsed_function().function().Owner());
2286 Value* type_arguments_val = BuildInstantiatorTypeArguments( 2278 Value* type_arguments_val = BuildInstantiatorTypeArguments(
2287 node->token_pos(), instantiator_class, NULL); 2279 node->token_pos(), instantiator_class, NULL);
2288 2280
2289 const bool use_instantiator_type_args = 2281 const bool use_instantiator_type_args =
2290 node->type_arguments().IsUninstantiatedIdentity() || 2282 node->type_arguments().IsUninstantiatedIdentity() ||
2291 node->type_arguments().CanShareInstantiatorTypeArguments( 2283 node->type_arguments().CanShareInstantiatorTypeArguments(
2292 instantiator_class); 2284 instantiator_class);
2293 2285
2294 if (!use_instantiator_type_args) { 2286 if (!use_instantiator_type_args) {
2295 type_arguments_val = 2287 const intptr_t len = node->type_arguments().Length();
2296 Bind(BuildStoreTemp(temp, type_arguments_val)); 2288 if (node->type_arguments().IsRawInstantiatedRaw(len)) {
2297 type_arguments_val = Bind( 2289 type_arguments_val =
2298 new ExtractConstructorTypeArgumentsInstr( 2290 Bind(BuildStoreTemp(temp, type_arguments_val));
2299 node->token_pos(), 2291 type_arguments_val = Bind(
2300 node->type_arguments(), 2292 new ExtractConstructorTypeArgumentsInstr(
2301 instantiator_class, 2293 node->token_pos(),
2302 type_arguments_val)); 2294 node->type_arguments(),
2295 instantiator_class,
2296 type_arguments_val));
2297 } else {
2298 Do(BuildStoreTemp(temp, type_arguments_val));
2299 type_arguments_val = Bind(new ConstantInstr(node->type_arguments()));
2300 }
2303 } 2301 }
2304 2302 call_arguments->Add(PushArgument(type_arguments_val));
2305 if (call_arguments != NULL) {
2306 ASSERT(type_arguments == NULL);
2307 call_arguments->Add(PushArgument(type_arguments_val));
2308 } else {
2309 ASSERT(type_arguments != NULL);
2310 *type_arguments = type_arguments_val;
2311 }
2312 2303
2313 Value* instantiator_val = NULL; 2304 Value* instantiator_val = NULL;
2314 if (!use_instantiator_type_args) { 2305 if (!use_instantiator_type_args) {
2315 instantiator_val = Bind(BuildLoadLocal(temp)); 2306 instantiator_val = Bind(BuildLoadLocal(temp));
2316 instantiator_val = 2307 const intptr_t len = node->type_arguments().Length();
2317 Bind(new ExtractConstructorInstantiatorInstr(node, 2308 if (node->type_arguments().IsRawInstantiatedRaw(len)) {
2318 instantiator_class, 2309 instantiator_val =
2319 instantiator_val)); 2310 Bind(new ExtractConstructorInstantiatorInstr(node,
2311 instantiator_class,
2312 instantiator_val));
2313 }
2320 } else { 2314 } else {
2321 // No instantiator required. 2315 // No instantiator required.
2322 instantiator_val = Bind(new ConstantInstr( 2316 instantiator_val = Bind(new ConstantInstr(
2323 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); 2317 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator))));
2324 } 2318 }
2325 2319 call_arguments->Add(PushArgument(instantiator_val));
2326 if (call_arguments != NULL) {
2327 ASSERT(instantiator == NULL);
2328 call_arguments->Add(PushArgument(instantiator_val));
2329 } else {
2330 ASSERT(instantiator != NULL);
2331 *instantiator = instantiator_val;
2332 }
2333 } 2320 }
2334 2321
2335 2322
2336 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 2323 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
2337 if (node->constructor().IsFactory()) { 2324 if (node->constructor().IsFactory()) {
2338 EffectGraphVisitor::VisitConstructorCallNode(node); 2325 EffectGraphVisitor::VisitConstructorCallNode(node);
2339 return; 2326 return;
2340 } 2327 }
2341 2328
2342 // t_n contains the allocated and initialized object. 2329 // t_n contains the allocated and initialized object.
(...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after
3389 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 3376 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
3390 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 3377 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
3391 OS::SNPrint(chars, len, kFormat, function_name, reason); 3378 OS::SNPrint(chars, len, kFormat, function_name, reason);
3392 const Error& error = Error::Handle( 3379 const Error& error = Error::Handle(
3393 LanguageError::New(String::Handle(String::New(chars)))); 3380 LanguageError::New(String::Handle(String::New(chars))));
3394 Isolate::Current()->long_jump_base()->Jump(1, error); 3381 Isolate::Current()->long_jump_base()->Jump(1, error);
3395 } 3382 }
3396 3383
3397 3384
3398 } // namespace dart 3385 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698