| Index: src/hydrogen.cc | 
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc | 
| index e7621d4d0f48b209e8553a1635fc904e9472597b..74434cd528b9dbc95bdb7e7f17fd1acbe57981dd 100644 | 
| --- a/src/hydrogen.cc | 
| +++ b/src/hydrogen.cc | 
| @@ -2427,6 +2427,22 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( | 
| IsFixedTypedArrayElementsKind(elements_kind)) { | 
| HValue* backing_store; | 
| if (IsExternalArrayElementsKind(elements_kind)) { | 
| +      NoObservableSideEffectsScope no_effects(this); | 
| +      HInstruction* buffer = Add<HLoadNamedField>( | 
| +          checked_object, nullptr, HObjectAccess::ForJSArrayBufferViewBuffer()); | 
| +      HInstruction* flags = Add<HLoadNamedField>( | 
| +          buffer, nullptr, HObjectAccess::ForJSArrayBufferFlag()); | 
| +      HValue* was_neutered_mask = | 
| +          Add<HConstant>(1 << JSArrayBuffer::kWasNeuteredBit); | 
| +      HValue* was_neutered_test = | 
| +          AddUncasted<HBitwise>(Token::BIT_AND, flags, was_neutered_mask); | 
| + | 
| +      IfBuilder if_was_neutered(this); | 
| +      if_was_neutered.If<HCompareNumericAndBranch>( | 
| +          was_neutered_test, graph()->GetConstant0(), Token::NE); | 
| +      if_was_neutered.ThenDeopt(Deoptimizer::kOutOfBounds); | 
| +      if_was_neutered.End(); | 
| + | 
| backing_store = Add<HLoadNamedField>( | 
| elements, nullptr, HObjectAccess::ForExternalArrayExternalPointer()); | 
| } else { | 
| @@ -9613,20 +9629,11 @@ void HGraphBuilder::BuildArrayBufferViewInitialization( | 
| Add<HStoreNamedField>( | 
| obj, | 
| HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); | 
| -    HObjectAccess weak_first_view_access = | 
| -        HObjectAccess::ForJSArrayBufferWeakFirstView(); | 
| -    Add<HStoreNamedField>( | 
| -        obj, HObjectAccess::ForJSArrayBufferViewWeakNext(), | 
| -        Add<HLoadNamedField>(buffer, nullptr, weak_first_view_access)); | 
| -    Add<HStoreNamedField>(buffer, weak_first_view_access, obj); | 
| } else { | 
| Add<HStoreNamedField>( | 
| obj, | 
| HObjectAccess::ForJSArrayBufferViewBuffer(), | 
| Add<HConstant>(static_cast<int32_t>(0))); | 
| -    Add<HStoreNamedField>(obj, | 
| -        HObjectAccess::ForJSArrayBufferViewWeakNext(), | 
| -        graph()->GetConstantUndefined()); | 
| } | 
| } | 
|  | 
| @@ -9920,36 +9927,62 @@ void HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength( | 
| } | 
|  | 
|  | 
| -void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength( | 
| -    CallRuntime* expr) { | 
| +void HOptimizedGraphBuilder::GenerateArrayBufferViewIndirectAccessor( | 
| +    CallRuntime* expr, HObjectAccess access) { | 
| +  NoObservableSideEffectsScope scope(this); | 
| DCHECK(expr->arguments()->length() == 1); | 
| CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); | 
| -  HValue* buffer = Pop(); | 
| -  HInstruction* result = New<HLoadNamedField>( | 
| -      buffer, nullptr, HObjectAccess::ForJSArrayBufferViewByteLength()); | 
| -  return ast_context()->ReturnInstruction(result, expr->id()); | 
| +  HValue* view = Pop(); | 
| +  HInstruction* buffer = Add<HLoadNamedField>( | 
| +      view, nullptr, HObjectAccess::ForJSArrayBufferViewBuffer()); | 
| +  HInstruction* field = Add<HLoadNamedField>(view, nullptr, access); | 
| + | 
| +  IfBuilder if_has_buffer(this); | 
| +  if_has_buffer.IfNot<HIsSmiAndBranch>(buffer); | 
| +  if_has_buffer.Then(); | 
| +  { | 
| +    HInstruction* flags = Add<HLoadNamedField>( | 
| +        buffer, nullptr, HObjectAccess::ForJSArrayBufferFlag()); | 
| +    HValue* was_neutered_mask = | 
| +        Add<HConstant>(1 << JSArrayBuffer::kWasNeuteredBit); | 
| +    HValue* was_neutered_test = | 
| +        AddUncasted<HBitwise>(Token::BIT_AND, flags, was_neutered_mask); | 
| + | 
| +    IfBuilder if_was_neutered(this); | 
| +    if_was_neutered.If<HCompareNumericAndBranch>( | 
| +        was_neutered_test, graph()->GetConstant0(), Token::NE); | 
| +    if_was_neutered.Then(); | 
| +    Push(graph()->GetConstant0()); | 
| +    if_was_neutered.Else(); | 
| +    Push(field); | 
| +    if_was_neutered.End(); | 
| +  } | 
| +  if_has_buffer.Else(); | 
| +  Push(field); | 
| +  if_has_buffer.End(); | 
| + | 
| +  return ast_context()->ReturnValue(Pop()); | 
| +} | 
| + | 
| + | 
| +void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength( | 
| +    CallRuntime* expr) { | 
| +  return GenerateArrayBufferViewIndirectAccessor( | 
| +      expr, HObjectAccess::ForJSArrayBufferViewByteLength()); | 
| } | 
|  | 
|  | 
| void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset( | 
| CallRuntime* expr) { | 
| -  DCHECK(expr->arguments()->length() == 1); | 
| -  CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); | 
| -  HValue* buffer = Pop(); | 
| -  HInstruction* result = New<HLoadNamedField>( | 
| -      buffer, nullptr, HObjectAccess::ForJSArrayBufferViewByteOffset()); | 
| -  return ast_context()->ReturnInstruction(result, expr->id()); | 
| +  return GenerateArrayBufferViewIndirectAccessor( | 
| +      expr, HObjectAccess::ForJSArrayBufferViewByteOffset()); | 
| } | 
|  | 
|  | 
| void HOptimizedGraphBuilder::GenerateTypedArrayGetLength( | 
| CallRuntime* expr) { | 
| -  DCHECK(expr->arguments()->length() == 1); | 
| -  CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); | 
| -  HValue* buffer = Pop(); | 
| -  HInstruction* result = New<HLoadNamedField>( | 
| -      buffer, nullptr, HObjectAccess::ForJSTypedArrayLength()); | 
| -  return ast_context()->ReturnInstruction(result, expr->id()); | 
| +  return GenerateArrayBufferViewIndirectAccessor( | 
| +      expr, HObjectAccess::ForJSTypedArrayLength()); | 
| } | 
|  | 
|  | 
|  |