Index: src/compiler/js-typed-lowering.cc |
diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc |
index 4c166e0dc53d3b2e6dd2319873de41bd230417cc..b3a4c78d599c969a6788c850fe260276eaf8b9d8 100644 |
--- a/src/compiler/js-typed-lowering.cc |
+++ b/src/compiler/js-typed-lowering.cc |
@@ -499,6 +499,85 @@ Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) { |
} |
+FieldAccess JSTypedLowering::FieldAccessForElements() { |
titzer
2014/08/28 09:45:09
Let's pull these out to an AccessHelper class.
Michael Starzinger
2014/08/28 10:38:40
Done. I called it just "Access" but I am happy to
titzer
2014/08/28 11:09:03
Maybe AccessBuilder...to prevent confusion between
|
+ return {kTaggedBase, JSTypedArray::kElementsOffset, |
+ graph()->zone()->isolate()->factory()->empty_string(), |
+ Type::Internal(), kMachAnyTagged}; |
+} |
+ |
+ |
+FieldAccess JSTypedLowering::FieldAccessForExternalPointer() { |
+ return {kTaggedBase, ExternalArray::kExternalPointerOffset, |
+ graph()->zone()->isolate()->factory()->empty_string(), |
+ Type::UntaggedPtr(), kMachPtr}; |
+} |
+ |
+ |
+static ElementAccess ElementAccessForTypedArray(BaseTaggedness taggedness, |
+ ExternalArrayType type, |
+ int header_size) { |
+ switch (type) { |
+ case kExternalInt8Array: |
+ return {taggedness, header_size, Type::Signed32(), kMachInt8}; |
+ case kExternalUint8Array: |
+ case kExternalUint8ClampedArray: |
+ return {taggedness, header_size, Type::Unsigned32(), kMachUint8}; |
+ case kExternalInt16Array: |
+ return {taggedness, header_size, Type::Signed32(), kMachInt16}; |
+ case kExternalUint16Array: |
+ return {taggedness, header_size, Type::Unsigned32(), kMachUint16}; |
+ case kExternalInt32Array: |
+ return {taggedness, header_size, Type::Signed32(), kMachInt32}; |
+ case kExternalUint32Array: |
+ return {taggedness, header_size, Type::Unsigned32(), kMachUint32}; |
+ case kExternalFloat32Array: |
+ return {taggedness, header_size, Type::Number(), kRepFloat32}; |
+ case kExternalFloat64Array: |
+ return {taggedness, header_size, Type::Number(), kRepFloat64}; |
+ } |
+ UNREACHABLE(); |
+ return {kUntaggedBase, 0, Type::None(), kMachNone}; |
+} |
+ |
+ |
+Reduction JSTypedLowering::ReduceJSPropertyLoad(Node* node) { |
+ Node* key = NodeProperties::GetValueInput(node, 1); |
+ Node* base = NodeProperties::GetValueInput(node, 0); |
+ Type* key_type = NodeProperties::GetBounds(key).upper; |
+ Type* base_type = NodeProperties::GetBounds(base).upper; |
+ // TODO(mstarzinger): This lowering is not correct if: |
+ // a) The typed array turns external (i.e. MaterializeArrayBuffer) |
+ // b) The typed array or it's buffer is neutered. |
+ // c) The index is out of bounds. |
+ if (base_type->IsConstant() && key_type->Is(Type::Integral32()) && |
+ base_type->AsConstant()->Value()->IsJSTypedArray()) { |
+ // JSLoadProperty(typed-array, int32) |
+ JSTypedArray* array = JSTypedArray::cast(*base_type->AsConstant()->Value()); |
+ ElementsKind elements_kind = array->map()->elements_kind(); |
+ ExternalArrayType type = array->type(); |
+ ElementAccess element_access; |
+ Node* elements = |
+ graph()->NewNode(simplified()->LoadField(FieldAccessForElements()), |
+ base, NodeProperties::GetEffectInput(node)); |
+ if (IsExternalArrayElementsKind(elements_kind)) { |
+ elements = graph()->NewNode( |
+ simplified()->LoadField(FieldAccessForExternalPointer()), elements, |
+ NodeProperties::GetEffectInput(node)); |
+ element_access = ElementAccessForTypedArray(kUntaggedBase, type, 0); |
titzer
2014/08/28 09:45:10
Maybe instead of passing the header size, you pass
Michael Starzinger
2014/08/28 10:38:40
Done.
|
+ } else { |
+ DCHECK(IsFixedTypedArrayElementsKind(elements_kind)); |
+ int offset = FixedTypedArrayBase::kDataOffset; |
+ element_access = ElementAccessForTypedArray(kTaggedBase, type, offset); |
+ } |
+ Node* value = |
+ graph()->NewNode(simplified()->LoadElement(element_access), elements, |
+ key, NodeProperties::GetEffectInput(node)); |
+ return ReplaceEagerly(node, value); |
+ } |
+ return NoChange(); |
+} |
+ |
+ |
static Reduction ReplaceWithReduction(Node* node, Reduction reduction) { |
if (reduction.Changed()) { |
NodeProperties::ReplaceWithValue(node, reduction.replacement()); |
@@ -573,6 +652,8 @@ Reduction JSTypedLowering::Reduce(Node* node) { |
case IrOpcode::kJSToString: |
return ReplaceWithReduction(node, |
ReduceJSToStringInput(node->InputAt(0))); |
+ case IrOpcode::kJSLoadProperty: |
+ return ReduceJSPropertyLoad(node); |
default: |
break; |
} |