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

Unified Diff: src/compiler/js-native-context-specialization.cc

Issue 2510553002: [turbofan] Specialize to (optimization time) known TypedArray instances. (Closed)
Patch Set: Created 4 years, 1 month 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 | « src/compiler/js-native-context-specialization.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/js-native-context-specialization.cc
diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc
index efe7cd623b27f9a5b6e1662b804d4cd6598adcae..fcf954e5c28aacb12593b8800b7486b755961ef8 100644
--- a/src/compiler/js-native-context-specialization.cc
+++ b/src/compiler/js-native-context-specialization.cc
@@ -171,8 +171,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
receiver, effect, control);
} else {
// Monomorphic property access.
- receiver = effect = graph()->NewNode(simplified()->CheckHeapObject(),
- receiver, effect, control);
+ receiver = BuildCheckHeapObject(receiver, &effect, control);
effect = BuildCheckMaps(receiver, effect, control,
access_info.receiver_maps());
}
@@ -210,8 +209,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch);
receiverissmi_effect = effect;
} else {
- receiver = effect = graph()->NewNode(simplified()->CheckHeapObject(),
- receiver, effect, control);
+ receiver = BuildCheckHeapObject(receiver, &effect, control);
}
// Load the {receiver} map. The resulting effect is the dominating effect
@@ -520,8 +518,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
}
// Ensure that {receiver} is a heap object.
- receiver = effect = graph()->NewNode(simplified()->CheckHeapObject(),
- receiver, effect, control);
+ receiver = BuildCheckHeapObject(receiver, &effect, control);
// Check for the monomorphic case.
if (access_infos.size() == 1) {
@@ -1070,8 +1067,7 @@ JSNativeContextSpecialization::BuildPropertyAccess(
}
case MachineRepresentation::kTaggedPointer: {
// Ensure that {value} is a HeapObject.
- value = effect = graph()->NewNode(simplified()->CheckHeapObject(),
- value, effect, control);
+ value = BuildCheckHeapObject(value, &effect, control);
Handle<Map> field_map;
if (access_info.field_map().ToHandle(&field_map)) {
// Emit a map check for the value.
@@ -1165,34 +1161,61 @@ JSNativeContextSpecialization::BuildElementAccess(
ElementsKind elements_kind = access_info.elements_kind();
MapList const& receiver_maps = access_info.receiver_maps();
- // Load the elements for the {receiver}.
- Node* elements = effect = graph()->NewNode(
- simplified()->LoadField(AccessBuilder::ForJSObjectElements()), receiver,
- effect, control);
-
- // Don't try to store to a copy-on-write backing store.
- if (access_mode == AccessMode::kStore &&
- IsFastSmiOrObjectElementsKind(elements_kind) &&
- store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
- effect =
- graph()->NewNode(simplified()->CheckMaps(1), elements,
- jsgraph()->FixedArrayMapConstant(), effect, control);
- }
-
if (IsFixedTypedArrayElementsKind(elements_kind)) {
- // Load the {receiver}s length.
- Node* length = effect = graph()->NewNode(
- simplified()->LoadField(AccessBuilder::ForJSTypedArrayLength()),
- receiver, effect, control);
+ Node* buffer;
+ Node* length;
+ Node* base_pointer;
+ Node* external_pointer;
+
+ // Check if we can constant-fold information about the {receiver} (i.e.
+ // for asm.js-like code patterns).
+ HeapObjectMatcher m(receiver);
+ if (m.HasValue() && m.Value()->IsJSTypedArray()) {
+ Handle<JSTypedArray> typed_array = Handle<JSTypedArray>::cast(m.Value());
+
+ // Determine the {receiver}s (known) length.
+ length = jsgraph()->Constant(typed_array->length_value());
+
+ // Check if the {receiver}s buffer was neutered.
+ buffer = jsgraph()->HeapConstant(typed_array->GetBuffer());
+
+ // Load the (known) base and external pointer for the {receiver}. The
+ // {external_pointer} might be invalid if the {buffer} was neutered, so
+ // we need to make sure that any access is properly guarded.
+ base_pointer = jsgraph()->ZeroConstant();
+ external_pointer = jsgraph()->PointerConstant(
+ FixedTypedArrayBase::cast(typed_array->elements())
+ ->external_pointer());
+ } else {
+ // Load the {receiver}s length.
+ length = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForJSTypedArrayLength()),
+ receiver, effect, control);
+
+ // Load the buffer for the {receiver}.
+ buffer = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForJSArrayBufferViewBuffer()),
+ receiver, effect, control);
+
+ // Load the elements for the {receiver}.
+ Node* elements = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForJSObjectElements()),
+ receiver, effect, control);
+
+ // Load the base and external pointer for the {receiver}s {elements}.
+ base_pointer = effect = graph()->NewNode(
+ simplified()->LoadField(
+ AccessBuilder::ForFixedTypedArrayBaseBasePointer()),
+ elements, effect, control);
+ external_pointer = effect = graph()->NewNode(
+ simplified()->LoadField(
+ AccessBuilder::ForFixedTypedArrayBaseExternalPointer()),
+ elements, effect, control);
+ }
- // Check if the {receiver}s buffer was neutered.
- Node* buffer = effect = graph()->NewNode(
- simplified()->LoadField(AccessBuilder::ForJSArrayBufferViewBuffer()),
- receiver, effect, control);
+ // Default to zero if the {receiver}s buffer was neutered.
Node* check = effect = graph()->NewNode(
simplified()->ArrayBufferWasNeutered(), buffer, effect, control);
-
- // Default to zero if the {receiver}s buffer was neutered.
length = graph()->NewNode(
common()->Select(MachineRepresentation::kTagged, BranchHint::kFalse),
check, jsgraph()->ZeroConstant(), length);
@@ -1211,16 +1234,6 @@ JSNativeContextSpecialization::BuildElementAccess(
length, effect, control);
}
- // Load the base and external pointer for the {receiver}.
- Node* base_pointer = effect = graph()->NewNode(
- simplified()->LoadField(
- AccessBuilder::ForFixedTypedArrayBaseBasePointer()),
- elements, effect, control);
- Node* external_pointer = effect = graph()->NewNode(
- simplified()->LoadField(
- AccessBuilder::ForFixedTypedArrayBaseExternalPointer()),
- elements, effect, control);
-
// Access the actual element.
ExternalArrayType external_array_type =
GetArrayTypeFromElementsKind(elements_kind);
@@ -1280,6 +1293,20 @@ JSNativeContextSpecialization::BuildElementAccess(
}
}
} else {
+ // Load the elements for the {receiver}.
+ Node* elements = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForJSObjectElements()), receiver,
+ effect, control);
+
+ // Don't try to store to a copy-on-write backing store.
+ if (access_mode == AccessMode::kStore &&
+ IsFastSmiOrObjectElementsKind(elements_kind) &&
+ store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
+ effect =
+ graph()->NewNode(simplified()->CheckMaps(1), elements,
+ jsgraph()->FixedArrayMapConstant(), effect, control);
+ }
+
// Check if the {receiver} is a JSArray.
bool receiver_is_jsarray = HasOnlyJSArrayMaps(receiver_maps);
@@ -1468,6 +1495,33 @@ JSNativeContextSpecialization::InlineApiCall(
return ValueEffectControl(value0, effect0, control0);
}
+Node* JSNativeContextSpecialization::BuildCheckHeapObject(Node* receiver,
+ Node** effect,
+ Node* control) {
+ switch (receiver->opcode()) {
+ case IrOpcode::kHeapConstant:
+ case IrOpcode::kJSCreate:
+ case IrOpcode::kJSCreateArguments:
+ case IrOpcode::kJSCreateArray:
+ case IrOpcode::kJSCreateClosure:
+ case IrOpcode::kJSCreateIterResultObject:
+ case IrOpcode::kJSCreateLiteralArray:
+ case IrOpcode::kJSCreateLiteralObject:
+ case IrOpcode::kJSCreateLiteralRegExp:
+ case IrOpcode::kJSConvertReceiver:
+ case IrOpcode::kJSToName:
+ case IrOpcode::kJSToString:
+ case IrOpcode::kJSToObject:
+ case IrOpcode::kJSTypeOf: {
+ return receiver;
+ }
+ default: {
+ return *effect = graph()->NewNode(simplified()->CheckHeapObject(),
+ receiver, *effect, control);
+ }
+ }
+}
+
Node* JSNativeContextSpecialization::BuildCheckMaps(
Node* receiver, Node* effect, Node* control,
std::vector<Handle<Map>> const& maps) {
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698