| Index: runtime/vm/kernel_binary.cc | 
| diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc | 
| index 55cee46d294e04bf29850131a0b9a4788703499d..220355deebc327ddd04a3269cca27296af7d895b 100644 | 
| --- a/runtime/vm/kernel_binary.cc | 
| +++ b/runtime/vm/kernel_binary.cc | 
| @@ -201,6 +201,10 @@ Library* Library::ReadFrom(Reader* reader) { | 
|  | 
| fields().ReadFrom<Field>(reader, this); | 
| procedures().ReadFrom<Procedure>(reader, this); | 
| + | 
| +  can_stream_ = | 
| +      classes().CanStream() && fields().CanStream() && procedures().CanStream(); | 
| + | 
| return this; | 
| } | 
|  | 
| @@ -231,6 +235,8 @@ Class* Class::ReadFrom(Reader* reader) { | 
| reader->record_token_position(position_); | 
| annotations_.ReadFromStatic<Expression>(reader); | 
|  | 
| +  can_stream_ = annotations_.CanStream(); | 
| + | 
| return this; | 
| } | 
|  | 
| @@ -251,6 +257,9 @@ NormalClass* NormalClass::ReadFrom(Reader* reader) { | 
| constructors_.ReadFrom<Constructor>(reader, this); | 
| procedures_.ReadFrom<Procedure>(reader, this); | 
|  | 
| +  can_stream_ = can_stream_ && fields_.CanStream() && | 
| +                constructors_.CanStream() && procedures_.CanStream(); | 
| + | 
| return this; | 
| } | 
|  | 
| @@ -266,6 +275,9 @@ MixinClass* MixinClass::ReadFrom(Reader* reader) { | 
| implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >( | 
| reader); | 
| constructors_.ReadFrom<Constructor>(reader, this); | 
| + | 
| +  can_stream_ = constructors_.CanStream(); | 
| + | 
| return this; | 
| } | 
|  | 
| @@ -318,6 +330,10 @@ Field* Field::ReadFrom(Reader* reader) { | 
| annotations_.ReadFromStatic<Expression>(reader); | 
| type_ = DartType::ReadFrom(reader); | 
| initializer_ = reader->ReadOptional<Expression>(); | 
| + | 
| +  can_stream_ = (initializer_ == NULL || initializer_->can_stream()) && | 
| +                annotations_.CanStream(); | 
| + | 
| return this; | 
| } | 
|  | 
| @@ -336,6 +352,10 @@ Constructor* Constructor::ReadFrom(Reader* reader) { | 
| annotations_.ReadFromStatic<Expression>(reader); | 
| function_ = FunctionNode::ReadFrom(reader); | 
| initializers_.ReadFromStatic<Initializer>(reader); | 
| + | 
| +  can_stream_ = annotations_.CanStream() && function_->can_stream() && | 
| +                initializers_.CanStream(); | 
| + | 
| return this; | 
| } | 
|  | 
| @@ -358,6 +378,10 @@ Procedure* Procedure::ReadFrom(Reader* reader) { | 
| reader->record_token_position(end_position_); | 
| annotations_.ReadFromStatic<Expression>(reader); | 
| function_ = reader->ReadOptional<FunctionNode>(); | 
| + | 
| +  can_stream_ = annotations_.CanStream() && | 
| +                (function_ == NULL || function_->can_stream()); | 
| + | 
| return this; | 
| } | 
|  | 
| @@ -394,6 +418,9 @@ FieldInitializer* FieldInitializer::ReadFromImpl(Reader* reader) { | 
| FieldInitializer* initializer = new FieldInitializer(); | 
| initializer->field_reference_ = Reference::ReadMemberFrom(reader); | 
| initializer->value_ = Expression::ReadFrom(reader); | 
| + | 
| +  initializer->can_stream_ = initializer->value_->can_stream(); | 
| + | 
| return initializer; | 
| } | 
|  | 
| @@ -403,6 +430,9 @@ SuperInitializer* SuperInitializer::ReadFromImpl(Reader* reader) { | 
| SuperInitializer* init = new SuperInitializer(); | 
| init->target_reference_ = Reference::ReadMemberFrom(reader); | 
| init->arguments_ = Arguments::ReadFrom(reader); | 
| + | 
| +  init->can_stream_ = init->arguments_->can_stream(); | 
| + | 
| return init; | 
| } | 
|  | 
| @@ -412,6 +442,9 @@ RedirectingInitializer* RedirectingInitializer::ReadFromImpl(Reader* reader) { | 
| RedirectingInitializer* init = new RedirectingInitializer(); | 
| init->target_reference_ = Reference::ReadMemberFrom(reader); | 
| init->arguments_ = Arguments::ReadFrom(reader); | 
| + | 
| +  init->can_stream_ = init->arguments_->can_stream(); | 
| + | 
| return init; | 
| } | 
|  | 
| @@ -420,6 +453,9 @@ LocalInitializer* LocalInitializer::ReadFromImpl(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| LocalInitializer* init = new LocalInitializer(); | 
| init->variable_ = VariableDeclaration::ReadFromImpl(reader, false); | 
| + | 
| +  init->can_stream_ = init->variable_->can_stream(); | 
| + | 
| return init; | 
| } | 
|  | 
| @@ -548,7 +584,9 @@ VariableGet* VariableGet::ReadFrom(Reader* reader) { | 
| VariableGet* get = new VariableGet(); | 
| get->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| get->position_ = reader->ReadPosition(); | 
| +  get->variable_kernel_offset_ = reader->ReadUInt(); | 
| get->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt()); | 
| +  ASSERT(get->variable_->kernel_offset() == get->variable_kernel_offset_); | 
| reader->ReadOptional<DartType>();  // Unused promoted type. | 
| return get; | 
| } | 
| @@ -559,7 +597,9 @@ VariableGet* VariableGet::ReadFrom(Reader* reader, uint8_t payload) { | 
| VariableGet* get = new VariableGet(); | 
| get->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| get->position_ = reader->ReadPosition(); | 
| +  get->variable_kernel_offset_ = reader->ReadUInt(); | 
| get->variable_ = reader->helper()->variables().Lookup(payload); | 
| +  ASSERT(get->variable_->kernel_offset() == get->variable_kernel_offset_); | 
| return get; | 
| } | 
|  | 
| @@ -569,8 +609,13 @@ VariableSet* VariableSet::ReadFrom(Reader* reader) { | 
| VariableSet* set = new VariableSet(); | 
| set->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| set->position_ = reader->ReadPosition(); | 
| +  set->variable_kernel_offset_ = reader->ReadUInt(); | 
| set->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt()); | 
| +  ASSERT(set->variable_->kernel_offset() == set->variable_kernel_offset_); | 
| set->expression_ = Expression::ReadFrom(reader); | 
| + | 
| +  set->can_stream_ = set->expression_->can_stream(); | 
| + | 
| return set; | 
| } | 
|  | 
| @@ -581,7 +626,12 @@ VariableSet* VariableSet::ReadFrom(Reader* reader, uint8_t payload) { | 
| set->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| set->variable_ = reader->helper()->variables().Lookup(payload); | 
| set->position_ = reader->ReadPosition(); | 
| +  set->variable_kernel_offset_ = reader->ReadUInt(); | 
| +  ASSERT(set->variable_->kernel_offset() == set->variable_kernel_offset_); | 
| set->expression_ = Expression::ReadFrom(reader); | 
| + | 
| +  set->can_stream_ = set->expression_->can_stream(); | 
| + | 
| return set; | 
| } | 
|  | 
| @@ -594,6 +644,9 @@ PropertyGet* PropertyGet::ReadFrom(Reader* reader) { | 
| get->receiver_ = Expression::ReadFrom(reader); | 
| get->name_ = Name::ReadFrom(reader); | 
| get->interface_target_reference_ = Reference::ReadMemberFrom(reader, true); | 
| + | 
| +  get->can_stream_ = get->receiver_->can_stream(); | 
| + | 
| return get; | 
| } | 
|  | 
| @@ -607,6 +660,9 @@ PropertySet* PropertySet::ReadFrom(Reader* reader) { | 
| set->name_ = Name::ReadFrom(reader); | 
| set->value_ = Expression::ReadFrom(reader); | 
| set->interface_target_reference_ = Reference::ReadMemberFrom(reader, true); | 
| + | 
| +  set->can_stream_ = set->receiver_->can_stream() && set->value_->can_stream(); | 
| + | 
| return set; | 
| } | 
|  | 
| @@ -618,6 +674,9 @@ DirectPropertyGet* DirectPropertyGet::ReadFrom(Reader* reader) { | 
| get->position_ = reader->ReadPosition(); | 
| get->receiver_ = Expression::ReadFrom(reader); | 
| get->target_reference_ = Reference::ReadMemberFrom(reader); | 
| + | 
| +  get->can_stream_ = get->receiver_->can_stream(); | 
| + | 
| return get; | 
| } | 
|  | 
| @@ -630,6 +689,9 @@ DirectPropertySet* DirectPropertySet::ReadFrom(Reader* reader) { | 
| set->receiver_ = Expression::ReadFrom(reader); | 
| set->target_reference_ = Reference::ReadMemberFrom(reader); | 
| set->value_ = Expression::ReadFrom(reader); | 
| + | 
| +  set->can_stream_ = set->receiver_->can_stream() && set->value_->can_stream(); | 
| + | 
| return set; | 
| } | 
|  | 
| @@ -651,6 +713,9 @@ StaticSet* StaticSet::ReadFrom(Reader* reader) { | 
| set->position_ = reader->ReadPosition(); | 
| set->target_reference_ = Reference::ReadMemberFrom(reader); | 
| set->expression_ = Expression::ReadFrom(reader); | 
| + | 
| +  set->can_stream_ = set->expression_->can_stream(); | 
| + | 
| return set; | 
| } | 
|  | 
| @@ -658,9 +723,15 @@ StaticSet* StaticSet::ReadFrom(Reader* reader) { | 
| Arguments* Arguments::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| Arguments* arguments = new Arguments(); | 
| +  intptr_t num_arguments = reader->ReadUInt(); | 
| arguments->types().ReadFromStatic<DartType>(reader); | 
| arguments->positional().ReadFromStatic<Expression>(reader); | 
| arguments->named().ReadFromStatic<NamedExpression>(reader); | 
| +  ASSERT(arguments->count() == num_arguments); | 
| + | 
| +  arguments->can_stream_ = | 
| +      arguments->positional().CanStream() && arguments->named().CanStream(); | 
| + | 
| return arguments; | 
| } | 
|  | 
| @@ -669,7 +740,11 @@ NamedExpression* NamedExpression::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| StringIndex name_index(reader->ReadUInt()); | 
| Expression* expression = Expression::ReadFrom(reader); | 
| -  return new NamedExpression(name_index, expression); | 
| +  NamedExpression* named = new NamedExpression(name_index, expression); | 
| + | 
| +  named->can_stream_ = expression->can_stream(); | 
| + | 
| +  return named; | 
| } | 
|  | 
|  | 
| @@ -683,6 +758,10 @@ MethodInvocation* MethodInvocation::ReadFrom(Reader* reader) { | 
| invocation->arguments_ = Arguments::ReadFrom(reader); | 
| invocation->interface_target_reference_ = | 
| Reference::ReadMemberFrom(reader, true); | 
| + | 
| +  invocation->can_stream_ = invocation->receiver_->can_stream() && | 
| +                            invocation->arguments_->can_stream(); | 
| + | 
| return invocation; | 
| } | 
|  | 
| @@ -694,6 +773,10 @@ DirectMethodInvocation* DirectMethodInvocation::ReadFrom(Reader* reader) { | 
| invocation->receiver_ = Expression::ReadFrom(reader); | 
| invocation->target_reference_ = Reference::ReadMemberFrom(reader); | 
| invocation->arguments_ = Arguments::ReadFrom(reader); | 
| + | 
| +  invocation->can_stream_ = invocation->receiver_->can_stream() && | 
| +                            invocation->arguments_->can_stream(); | 
| + | 
| return invocation; | 
| } | 
|  | 
| @@ -706,6 +789,9 @@ StaticInvocation* StaticInvocation::ReadFrom(Reader* reader, bool is_const) { | 
| invocation->position_ = reader->ReadPosition(); | 
| invocation->procedure_reference_ = Reference::ReadMemberFrom(reader); | 
| invocation->arguments_ = Arguments::ReadFrom(reader); | 
| + | 
| +  invocation->can_stream_ = invocation->arguments_->can_stream(); | 
| + | 
| return invocation; | 
| } | 
|  | 
| @@ -719,6 +805,9 @@ ConstructorInvocation* ConstructorInvocation::ReadFrom(Reader* reader, | 
| invocation->position_ = reader->ReadPosition(); | 
| invocation->target_reference_ = Reference::ReadMemberFrom(reader); | 
| invocation->arguments_ = Arguments::ReadFrom(reader); | 
| + | 
| +  invocation->can_stream_ = invocation->arguments_->can_stream(); | 
| + | 
| return invocation; | 
| } | 
|  | 
| @@ -728,6 +817,9 @@ Not* Not::ReadFrom(Reader* reader) { | 
| Not* n = new Not(); | 
| n->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| n->expression_ = Expression::ReadFrom(reader); | 
| + | 
| +  n->can_stream_ = n->expression_->can_stream(); | 
| + | 
| return n; | 
| } | 
|  | 
| @@ -739,6 +831,9 @@ LogicalExpression* LogicalExpression::ReadFrom(Reader* reader) { | 
| expr->left_ = Expression::ReadFrom(reader); | 
| expr->operator_ = static_cast<Operator>(reader->ReadByte()); | 
| expr->right_ = Expression::ReadFrom(reader); | 
| + | 
| +  expr->can_stream_ = expr->left_->can_stream() && expr->right_->can_stream(); | 
| + | 
| return expr; | 
| } | 
|  | 
| @@ -751,6 +846,11 @@ ConditionalExpression* ConditionalExpression::ReadFrom(Reader* reader) { | 
| expr->then_ = Expression::ReadFrom(reader); | 
| expr->otherwise_ = Expression::ReadFrom(reader); | 
| reader->ReadOptional<DartType>();  // Unused static type. | 
| + | 
| +  expr->can_stream_ = expr->condition_->can_stream() && | 
| +                      expr->then_->can_stream() && | 
| +                      expr->otherwise_->can_stream(); | 
| + | 
| return expr; | 
| } | 
|  | 
| @@ -761,6 +861,9 @@ StringConcatenation* StringConcatenation::ReadFrom(Reader* reader) { | 
| concat->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| concat->position_ = reader->ReadPosition(); | 
| concat->expressions_.ReadFromStatic<Expression>(reader); | 
| + | 
| +  concat->can_stream_ = concat->expressions_.CanStream(); | 
| + | 
| return concat; | 
| } | 
|  | 
| @@ -772,6 +875,9 @@ IsExpression* IsExpression::ReadFrom(Reader* reader) { | 
| expr->position_ = reader->ReadPosition(); | 
| expr->operand_ = Expression::ReadFrom(reader); | 
| expr->type_ = DartType::ReadFrom(reader); | 
| + | 
| +  expr->can_stream_ = expr->operand_->can_stream(); | 
| + | 
| return expr; | 
| } | 
|  | 
| @@ -783,6 +889,9 @@ AsExpression* AsExpression::ReadFrom(Reader* reader) { | 
| expr->position_ = reader->ReadPosition(); | 
| expr->operand_ = Expression::ReadFrom(reader); | 
| expr->type_ = DartType::ReadFrom(reader); | 
| + | 
| +  expr->can_stream_ = expr->operand_->can_stream(); | 
| + | 
| return expr; | 
| } | 
|  | 
| @@ -891,6 +1000,9 @@ Throw* Throw::ReadFrom(Reader* reader) { | 
| t->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| t->position_ = reader->ReadPosition(); | 
| t->expression_ = Expression::ReadFrom(reader); | 
| + | 
| +  t->can_stream_ = t->expression_->can_stream(); | 
| + | 
| return t; | 
| } | 
|  | 
| @@ -903,6 +1015,9 @@ ListLiteral* ListLiteral::ReadFrom(Reader* reader, bool is_const) { | 
| literal->position_ = reader->ReadPosition(); | 
| literal->type_ = DartType::ReadFrom(reader); | 
| literal->expressions_.ReadFromStatic<Expression>(reader); | 
| + | 
| +  literal->can_stream_ = literal->expressions_.CanStream(); | 
| + | 
| return literal; | 
| } | 
|  | 
| @@ -916,6 +1031,9 @@ MapLiteral* MapLiteral::ReadFrom(Reader* reader, bool is_const) { | 
| literal->key_type_ = DartType::ReadFrom(reader); | 
| literal->value_type_ = DartType::ReadFrom(reader); | 
| literal->entries_.ReadFromStatic<MapEntry>(reader); | 
| + | 
| +  literal->can_stream_ = literal->entries_.CanStream(); | 
| + | 
| return literal; | 
| } | 
|  | 
| @@ -924,6 +1042,9 @@ MapEntry* MapEntry::ReadFrom(Reader* reader) { | 
| MapEntry* entry = new MapEntry(); | 
| entry->key_ = Expression::ReadFrom(reader); | 
| entry->value_ = Expression::ReadFrom(reader); | 
| + | 
| +  entry->can_stream_ = entry->key_->can_stream() && entry->value_->can_stream(); | 
| + | 
| return entry; | 
| } | 
|  | 
| @@ -933,6 +1054,9 @@ AwaitExpression* AwaitExpression::ReadFrom(Reader* reader) { | 
| AwaitExpression* await = new AwaitExpression(); | 
| await->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| await->operand_ = Expression::ReadFrom(reader); | 
| + | 
| +  await->can_stream_ = await->operand_->can_stream(); | 
| + | 
| return await; | 
| } | 
|  | 
| @@ -943,6 +1067,9 @@ FunctionExpression* FunctionExpression::ReadFrom(Reader* reader) { | 
| FunctionExpression* expr = new FunctionExpression(); | 
| expr->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| expr->function_ = FunctionNode::ReadFrom(reader); | 
| + | 
| +  expr->can_stream_ = false; | 
| + | 
| return expr; | 
| } | 
|  | 
| @@ -959,6 +1086,8 @@ Let* Let::ReadFrom(Reader* reader) { | 
| let->position_ = reader->min_position(); | 
| let->end_position_ = reader->max_position(); | 
|  | 
| +  let->can_stream_ = let->variable_->can_stream() && let->body_->can_stream(); | 
| + | 
| return let; | 
| } | 
|  | 
| @@ -983,6 +1112,8 @@ VectorGet* VectorGet::ReadFrom(Reader* reader) { | 
| vector_get->vector_expression_ = Expression::ReadFrom(reader); | 
| vector_get->index_ = reader->ReadUInt(); | 
|  | 
| +  vector_get->can_stream_ = false; | 
| + | 
| return vector_get; | 
| } | 
|  | 
| @@ -996,6 +1127,8 @@ VectorSet* VectorSet::ReadFrom(Reader* reader) { | 
| vector_set->index_ = reader->ReadUInt(); | 
| vector_set->value_ = Expression::ReadFrom(reader); | 
|  | 
| +  vector_set->can_stream_ = false; | 
| + | 
| return vector_set; | 
| } | 
|  | 
| @@ -1008,6 +1141,8 @@ VectorCopy* VectorCopy::ReadFrom(Reader* reader) { | 
| reader->offset() - 1;  // -1 to include tag byte. | 
| vector_copy->vector_expression_ = Expression::ReadFrom(reader); | 
|  | 
| +  vector_copy->can_stream_ = false; | 
| + | 
| return vector_copy; | 
| } | 
|  | 
| @@ -1024,6 +1159,8 @@ ClosureCreation* ClosureCreation::ReadFrom(Reader* reader) { | 
| closure_creation->function_type_ = | 
| FunctionType::Cast(DartType::ReadFrom(reader)); | 
|  | 
| +  closure_creation->can_stream_ = false; | 
| + | 
| return closure_creation; | 
| } | 
|  | 
| @@ -1083,13 +1220,22 @@ Statement* Statement::ReadFrom(Reader* reader) { | 
|  | 
| InvalidStatement* InvalidStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| -  return new InvalidStatement(); | 
| +  InvalidStatement* stmt = new InvalidStatement(); | 
| +  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| +  return stmt; | 
| } | 
|  | 
|  | 
| ExpressionStatement* ExpressionStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| -  return new ExpressionStatement(Expression::ReadFrom(reader)); | 
| +  intptr_t offset = reader->offset() - 1;  // -1 to include tag byte. | 
| +  ExpressionStatement* stmt = | 
| +      new ExpressionStatement(Expression::ReadFrom(reader)); | 
| +  stmt->kernel_offset_ = offset; | 
| + | 
| +  stmt->can_stream_ = stmt->expression_->can_stream(); | 
| + | 
| +  return stmt; | 
| } | 
|  | 
|  | 
| @@ -1104,21 +1250,30 @@ Block* Block::ReadFromImpl(Reader* reader) { | 
| block->position_ = reader->min_position(); | 
| block->end_position_ = reader->max_position(); | 
|  | 
| +  block->can_stream_ = block->statements().CanStream(); | 
| + | 
| return block; | 
| } | 
|  | 
|  | 
| EmptyStatement* EmptyStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| -  return new EmptyStatement(); | 
| +  EmptyStatement* stmt = new EmptyStatement(); | 
| +  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| +  return stmt; | 
| } | 
|  | 
|  | 
| AssertStatement* AssertStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| AssertStatement* stmt = new AssertStatement(); | 
| +  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| stmt->condition_ = Expression::ReadFrom(reader); | 
| stmt->message_ = reader->ReadOptional<Expression>(); | 
| + | 
| +  stmt->can_stream_ = stmt->condition_->can_stream() && | 
| +                      (stmt->message_ == NULL || stmt->message_->can_stream()); | 
| + | 
| return stmt; | 
| } | 
|  | 
| @@ -1126,9 +1281,14 @@ AssertStatement* AssertStatement::ReadFrom(Reader* reader) { | 
| LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| LabeledStatement* stmt = new LabeledStatement(); | 
| +  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| + | 
| reader->helper()->labels()->Push(stmt); | 
| stmt->body_ = Statement::ReadFrom(reader); | 
| reader->helper()->labels()->Pop(stmt); | 
| + | 
| +  stmt->can_stream_ = stmt->body_->can_stream(); | 
| + | 
| return stmt; | 
| } | 
|  | 
| @@ -1136,8 +1296,9 @@ LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) { | 
| BreakStatement* BreakStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| BreakStatement* stmt = new BreakStatement(); | 
| +  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| stmt->position_ = reader->ReadPosition(); | 
| -  stmt->target_ = reader->helper()->labels()->Lookup(reader->ReadUInt()); | 
| +  stmt->target_index_ = reader->ReadUInt(); | 
| return stmt; | 
| } | 
|  | 
| @@ -1145,8 +1306,13 @@ BreakStatement* BreakStatement::ReadFrom(Reader* reader) { | 
| WhileStatement* WhileStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| WhileStatement* stmt = new WhileStatement(); | 
| +  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| stmt->condition_ = Expression::ReadFrom(reader); | 
| stmt->body_ = Statement::ReadFrom(reader); | 
| + | 
| +  stmt->can_stream_ = | 
| +      stmt->condition_->can_stream() && stmt->body_->can_stream(); | 
| + | 
| return stmt; | 
| } | 
|  | 
| @@ -1154,8 +1320,13 @@ WhileStatement* WhileStatement::ReadFrom(Reader* reader) { | 
| DoStatement* DoStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| DoStatement* dostmt = new DoStatement(); | 
| +  dostmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| dostmt->body_ = Statement::ReadFrom(reader); | 
| dostmt->condition_ = Expression::ReadFrom(reader); | 
| + | 
| +  dostmt->can_stream_ = | 
| +      dostmt->body_->can_stream() && dostmt->condition_->can_stream(); | 
| + | 
| return dostmt; | 
| } | 
|  | 
| @@ -1174,6 +1345,11 @@ ForStatement* ForStatement::ReadFrom(Reader* reader) { | 
| forstmt->end_position_ = reader->max_position(); | 
| forstmt->position_ = reader->min_position(); | 
|  | 
| +  forstmt->can_stream_ = | 
| +      forstmt->body_->can_stream() && | 
| +      (forstmt->condition_ == NULL || forstmt->condition_->can_stream()) && | 
| +      forstmt->variables_.CanStream() && forstmt->updates_.CanStream(); | 
| + | 
| return forstmt; | 
| } | 
|  | 
| @@ -1196,39 +1372,49 @@ ForInStatement* ForInStatement::ReadFrom(Reader* reader, bool is_async) { | 
| } | 
| forinstmt->variable_->set_end_position(forinstmt->position_); | 
|  | 
| +  forinstmt->can_stream_ = forinstmt->variable_->can_stream() && | 
| +                           forinstmt->iterable_->can_stream() && | 
| +                           forinstmt->body_->can_stream(); | 
| + | 
| return forinstmt; | 
| } | 
|  | 
|  | 
| SwitchStatement* SwitchStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| -  SwitchCaseScope<ReaderHelper> scope(reader->helper()); | 
| SwitchStatement* stmt = new SwitchStatement(); | 
| +  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| stmt->condition_ = Expression::ReadFrom(reader); | 
| -  // We need to explicitly create empty [SwitchCase]s first in order to add them | 
| -  // to the [SwitchCaseScope]. This is necessary since a [Statement] in a switch | 
| -  // case can refer to one defined later on. | 
| int count = reader->ReadUInt(); | 
| +  stmt->cases_.EnsureInitialized(count); | 
| for (intptr_t i = 0; i < count; i++) { | 
| SwitchCase* sc = stmt->cases_.GetOrCreate<SwitchCase>(i); | 
| -    reader->helper()->switch_cases().Push(sc); | 
| -  } | 
| -  for (intptr_t i = 0; i < count; i++) { | 
| -    SwitchCase* sc = stmt->cases_[i]; | 
| sc->ReadFrom(reader); | 
| } | 
| + | 
| +  stmt->can_stream_ = | 
| +      stmt->condition_->can_stream() && stmt->cases_.CanStream(); | 
| + | 
| return stmt; | 
| } | 
|  | 
|  | 
| SwitchCase* SwitchCase::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| -  expressions_.ReadFromStatic<Expression>(reader); | 
| -  for (intptr_t i = 0; i < expressions_.length(); ++i) { | 
| -    expressions_[i]->set_position(reader->ReadPosition()); | 
| +  int length = reader->ReadListLength(); | 
| +  expressions_.EnsureInitialized(length); | 
| + | 
| +  for (intptr_t i = 0; i < length; i++) { | 
| +    ASSERT(expressions_[i] == NULL); | 
| +    TokenPosition position = reader->ReadPosition(); | 
| +    expressions_[i] = Expression::ReadFrom(reader); | 
| +    expressions_[i]->set_position(position); | 
| } | 
| is_default_ = reader->ReadBool(); | 
| body_ = Statement::ReadFrom(reader); | 
| + | 
| +  can_stream_ = expressions_.CanStream() && body_->can_stream(); | 
| + | 
| return this; | 
| } | 
|  | 
| @@ -1236,7 +1422,9 @@ SwitchCase* SwitchCase::ReadFrom(Reader* reader) { | 
| ContinueSwitchStatement* ContinueSwitchStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| ContinueSwitchStatement* stmt = new ContinueSwitchStatement(); | 
| -  stmt->target_ = reader->helper()->switch_cases().Lookup(reader->ReadUInt()); | 
| +  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| +  stmt->target_index_ = reader->ReadUInt(); | 
| + | 
| return stmt; | 
| } | 
|  | 
| @@ -1244,9 +1432,15 @@ ContinueSwitchStatement* ContinueSwitchStatement::ReadFrom(Reader* reader) { | 
| IfStatement* IfStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| IfStatement* ifstmt = new IfStatement(); | 
| +  ifstmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| ifstmt->condition_ = Expression::ReadFrom(reader); | 
| ifstmt->then_ = Statement::ReadFrom(reader); | 
| ifstmt->otherwise_ = Statement::ReadFrom(reader); | 
| + | 
| +  ifstmt->can_stream_ = ifstmt->condition_->can_stream() && | 
| +                        ifstmt->then_->can_stream() && | 
| +                        ifstmt->otherwise_->can_stream(); | 
| + | 
| return ifstmt; | 
| } | 
|  | 
| @@ -1254,8 +1448,13 @@ IfStatement* IfStatement::ReadFrom(Reader* reader) { | 
| ReturnStatement* ReturnStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| ReturnStatement* ret = new ReturnStatement(); | 
| +  ret->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| ret->position_ = reader->ReadPosition(); | 
| ret->expression_ = reader->ReadOptional<Expression>(); | 
| + | 
| +  ret->can_stream_ = | 
| +      (ret->expression_ == NULL || ret->expression_->can_stream()); | 
| + | 
| return ret; | 
| } | 
|  | 
| @@ -1265,10 +1464,14 @@ TryCatch* TryCatch::ReadFrom(Reader* reader) { | 
| PositionScope scope(reader); | 
|  | 
| TryCatch* tc = new TryCatch(); | 
| +  tc->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| tc->body_ = Statement::ReadFrom(reader); | 
| +  reader->ReadBool();  // whether any catch needs a stacktrace. | 
| tc->catches_.ReadFromStatic<Catch>(reader); | 
| tc->position_ = reader->min_position(); | 
|  | 
| +  tc->can_stream_ = tc->body_->can_stream() && tc->catches_.CanStream(); | 
| + | 
| return tc; | 
| } | 
|  | 
| @@ -1289,6 +1492,8 @@ Catch* Catch::ReadFrom(Reader* reader) { | 
| c->end_position_ = reader->max_position(); | 
| c->position_ = reader->min_position(); | 
|  | 
| +  c->can_stream_ = c->body_->can_stream(); | 
| + | 
| return c; | 
| } | 
|  | 
| @@ -1296,8 +1501,12 @@ Catch* Catch::ReadFrom(Reader* reader) { | 
| TryFinally* TryFinally::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| TryFinally* tf = new TryFinally(); | 
| +  tf->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| tf->body_ = Statement::ReadFrom(reader); | 
| tf->finalizer_ = Statement::ReadFrom(reader); | 
| + | 
| +  tf->can_stream_ = tf->body_->can_stream() && tf->finalizer_->can_stream(); | 
| + | 
| return tf; | 
| } | 
|  | 
| @@ -1305,10 +1514,14 @@ TryFinally* TryFinally::ReadFrom(Reader* reader) { | 
| YieldStatement* YieldStatement::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| YieldStatement* stmt = new YieldStatement(); | 
| +  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte. | 
| stmt->position_ = reader->ReadPosition(); | 
| reader->record_yield_token_position(stmt->position_); | 
| stmt->flags_ = reader->ReadByte(); | 
| stmt->expression_ = Expression::ReadFrom(reader); | 
| + | 
| +  stmt->can_stream_ = stmt->expression_->can_stream(); | 
| + | 
| return stmt; | 
| } | 
|  | 
| @@ -1343,6 +1556,9 @@ VariableDeclaration* VariableDeclaration::ReadFromImpl(Reader* reader, | 
| decl->end_position_ = position; | 
| reader->helper()->variables().Push(decl); | 
|  | 
| +  decl->can_stream_ = | 
| +      (decl->initializer_ == NULL || decl->initializer_->can_stream()); | 
| + | 
| return decl; | 
| } | 
|  | 
| @@ -1355,6 +1571,9 @@ FunctionDeclaration* FunctionDeclaration::ReadFrom(Reader* reader) { | 
| decl->variable_ = VariableDeclaration::ReadFromImpl(reader, false); | 
| VariableScope<ReaderHelper> parameters(reader->helper()); | 
| decl->function_ = FunctionNode::ReadFrom(reader); | 
| + | 
| +  decl->can_stream_ = false; | 
| + | 
| return decl; | 
| } | 
|  | 
| @@ -1463,8 +1682,12 @@ FunctionType* FunctionType::ReadFrom(Reader* reader) { | 
| TypeParameterScope<ReaderHelper> scope(reader->helper()); | 
| type->type_parameters().ReadFrom(reader); | 
| type->required_parameter_count_ = reader->ReadUInt(); | 
| +  intptr_t total_parameter_count = reader->ReadUInt(); | 
| type->positional_parameters().ReadFromStatic<DartType>(reader); | 
| type->named_parameters().ReadFromStatic<NamedParameter>(reader); | 
| +  ASSERT(type->positional_parameters().length() + | 
| +             type->named_parameters().length() == | 
| +         total_parameter_count); | 
| type->return_type_ = DartType::ReadFrom(reader); | 
| return type; | 
| } | 
| @@ -1486,6 +1709,7 @@ TypeParameterType* TypeParameterType::ReadFrom(Reader* reader) { | 
| TypeParameterType* type = new TypeParameterType(); | 
| type->parameter_ = | 
| reader->helper()->type_parameters().Lookup(reader->ReadUInt()); | 
| +  reader->ReadUInt();  // binary offset of parameter | 
| // There is an optional promoted bound, currently ignored. | 
| delete reader->ReadOptional<DartType>(); | 
| return type; | 
| @@ -1546,6 +1770,8 @@ Program* Program::ReadFrom(Reader* reader) { | 
| program->main_method_reference_ = | 
| Reference::ReadMemberFrom(reader, /*allow_null=*/true); | 
|  | 
| +  program->can_stream_ = false; | 
| + | 
| return program; | 
| } | 
|  | 
| @@ -1573,12 +1799,19 @@ FunctionNode* FunctionNode::ReadFrom(Reader* reader) { | 
| reader->helper()); | 
| VariableScope<ReaderHelper> vars(reader->helper()); | 
| function->body_ = reader->ReadOptional<Statement>(); | 
| + | 
| +  function->can_stream_ = | 
| +      function->positional_parameters_.CanStream() && | 
| +      function->named_parameters_.CanStream() && | 
| +      (function->body_ == NULL || function->body_->can_stream()); | 
| + | 
| return function; | 
| } | 
|  | 
|  | 
| TypeParameter* TypeParameter::ReadFrom(Reader* reader) { | 
| TRACE_READ_OFFSET(); | 
| +  kernel_offset_ = reader->offset(); | 
| name_index_ = StringIndex(reader->ReadUInt()); | 
| bound_ = DartType::ReadFrom(reader); | 
| return this; | 
|  |