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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 23003026: Avoid array bounds check when allowed by guarded field. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_optimizer.cc
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index ba9a4d9fa9dbe68442e61735fcc7bd37da568e57..4841d52bf78706b067438d41f7a89f1c3271d31d 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -770,24 +770,52 @@ intptr_t FlowGraphOptimizer::PrepareIndexedOp(InstanceCallInstr* call,
call->env(),
Definition::kEffect);
- // Insert array length load and bounds check.
- const bool is_immutable =
- CheckArrayBoundInstr::IsFixedLengthArrayType(class_id);
- LoadFieldInstr* length =
- new LoadFieldInstr(new Value(*array),
- CheckArrayBoundInstr::LengthOffsetFor(class_id),
- Type::ZoneHandle(Type::SmiType()),
- is_immutable);
- length->set_result_cid(kSmiCid);
- length->set_recognized_kind(
- LoadFieldInstr::RecognizedKindFromArrayCid(class_id));
- InsertBefore(call, length, NULL, Definition::kValue);
- InsertBefore(call,
- new CheckArrayBoundInstr(new Value(length),
- new Value(*index),
- call->deopt_id()),
- call->env(),
- Definition::kEffect);
+ bool emit_bounds_check = true;
+ // Get the field for the array.
+ const Field* field = NULL;
+ if ((*array)->IsLoadField()) {
+ LoadFieldInstr* load_field_instr = (*array)->AsLoadField();
+ field = load_field_instr->field();
+ }
+ // Extract the guarded array length.
+ intptr_t guarded_array_length = -1;
+ if (field != NULL) {
+ if (field->guarded_list_length() >= 0) {
+ guarded_array_length = field->guarded_list_length();
+ }
+ }
+ Definition* i = *index;
+ // Check if we can skip emitting the bounds check.
+ if (i->IsConstant() && guarded_array_length >= 0) {
Florian Schneider 2013/08/23 08:26:15 When done here, it works only for constant index e
+ ConstantInstr* constant = i->AsConstant();
+ ASSERT(constant != NULL);
+ intptr_t ci = Smi::Cast(constant->value()).Value();
+ if (ci < guarded_array_length) {
+ emit_bounds_check = false;
+ }
+ }
+
+ if (emit_bounds_check) {
+ // Insert array length load and bounds check.
+ const bool is_immutable =
+ CheckArrayBoundInstr::IsFixedLengthArrayType(class_id);
+ LoadFieldInstr* length =
+ new LoadFieldInstr(new Value(*array),
+ CheckArrayBoundInstr::LengthOffsetFor(class_id),
+ Type::ZoneHandle(Type::SmiType()),
+ is_immutable);
+ length->set_result_cid(kSmiCid);
+ length->set_recognized_kind(
+ LoadFieldInstr::RecognizedKindFromArrayCid(class_id));
+ InsertBefore(call, length, NULL, Definition::kValue);
+ InsertBefore(call,
+ new CheckArrayBoundInstr(new Value(length),
+ new Value(*index),
+ call->deopt_id()),
+ call->env(),
+ Definition::kEffect);
+ }
+
if (class_id == kGrowableObjectArrayCid) {
// Insert data elements load.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698