| Index: src/compiler/js-context-specialization.cc | 
| diff --git a/src/compiler/js-context-specialization.cc b/src/compiler/js-context-specialization.cc | 
| index 0deb7cb38b668bbaf92fc2bb831ce501e6ab2f72..c9548ffd1c44d4c9284a73308b533a33d888aa1c 100644 | 
| --- a/src/compiler/js-context-specialization.cc | 
| +++ b/src/compiler/js-context-specialization.cc | 
| @@ -83,6 +83,45 @@ Reduction JSContextSpecialization::SimplifyJSStoreContext(Node* node, | 
| return Changed(node); | 
| } | 
|  | 
| +namespace { | 
| + | 
| +bool IsContextParameter(Node* node) { | 
| +  DCHECK_EQ(IrOpcode::kParameter, node->opcode()); | 
| +  Node* const start = NodeProperties::GetValueInput(node, 0); | 
| +  DCHECK_EQ(IrOpcode::kStart, start->opcode()); | 
| +  int const index = ParameterIndexOf(node->op()); | 
| +  // The context is always the last parameter to a JavaScript function, and | 
| +  // {Parameter} indices start at -1, so value outputs of {Start} look like | 
| +  // this: closure, receiver, param0, ..., paramN, context. | 
| +  return index == start->op()->ValueOutputCount() - 2; | 
| +} | 
| + | 
| +// Given a context {node} and the {distance} from that context to the target | 
| +// context (which we want to read from or store to), try to return a | 
| +// specialization context.  If successful, update {distance} to whatever | 
| +// distance remains from the specialization context. | 
| +MaybeHandle<Context> GetSpecializationContext(Node* node, size_t* distance, | 
| +                                              Maybe<OuterContext> maybe_outer) { | 
| +  switch (node->opcode()) { | 
| +    case IrOpcode::kHeapConstant: | 
| +      return Handle<Context>::cast(OpParameter<Handle<HeapObject>>(node)); | 
| +    case IrOpcode::kParameter: { | 
| +      OuterContext outer; | 
| +      if (maybe_outer.To(&outer) && IsContextParameter(node) && | 
| +          *distance >= outer.distance) { | 
| +        *distance -= outer.distance; | 
| +        return outer.context; | 
| +      } | 
| +      break; | 
| +    } | 
| +    default: | 
| +      break; | 
| +  } | 
| +  return MaybeHandle<Context>(); | 
| +} | 
| + | 
| +}  // anonymous namespace | 
| + | 
| Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) { | 
| DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); | 
|  | 
| @@ -90,14 +129,13 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) { | 
| size_t depth = access.depth(); | 
|  | 
| // First walk up the context chain in the graph as far as possible. | 
| -  Node* outer = NodeProperties::GetOuterContext(node, &depth); | 
| +  Node* context = NodeProperties::GetOuterContext(node, &depth); | 
|  | 
| Handle<Context> concrete; | 
| -  if (!NodeProperties::GetSpecializationContext(outer, context()) | 
| -           .ToHandle(&concrete)) { | 
| +  if (!GetSpecializationContext(context, &depth, outer()).ToHandle(&concrete)) { | 
| // We do not have a concrete context object, so we can only partially reduce | 
| // the load by folding-in the outer context node. | 
| -    return SimplifyJSLoadContext(node, outer, depth); | 
| +    return SimplifyJSLoadContext(node, context, depth); | 
| } | 
|  | 
| // Now walk up the concrete context chain for the remaining depth. | 
| @@ -139,14 +177,13 @@ Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) { | 
|  | 
| // First walk up the context chain in the graph until we reduce the depth to 0 | 
| // or hit a node that does not have a CreateXYZContext operator. | 
| -  Node* outer = NodeProperties::GetOuterContext(node, &depth); | 
| +  Node* context = NodeProperties::GetOuterContext(node, &depth); | 
|  | 
| Handle<Context> concrete; | 
| -  if (!NodeProperties::GetSpecializationContext(outer, context()) | 
| -           .ToHandle(&concrete)) { | 
| +  if (!GetSpecializationContext(context, &depth, outer()).ToHandle(&concrete)) { | 
| // We do not have a concrete context object, so we can only partially reduce | 
| // the load by folding-in the outer context node. | 
| -    return SimplifyJSStoreContext(node, outer, depth); | 
| +    return SimplifyJSStoreContext(node, context, depth); | 
| } | 
|  | 
| // Now walk up the concrete context chain for the remaining depth. | 
|  |