Commit 113b78e9 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Slightly refactor JSLoadGlobal specialization.

Reduce code duplication somewhat restructure the code to make
it easier to spot the code paths for the different property
cell types.

R=jarin@chromium.org
BUG=v8:4470
LOG=n

Review URL: https://codereview.chromium.org/1413383004

Cr-Commit-Position: refs/heads/master@{#31589}
parent e68adf45
...@@ -87,53 +87,52 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadGlobal(Node* node) { ...@@ -87,53 +87,52 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadGlobal(Node* node) {
return Replace(node, property_cell_value); return Replace(node, property_cell_value);
} }
// Load from constant/undefined global property can be constant-folded // Load from non-configurable, data property on the global can be lowered to
// with deoptimization support, by adding a code dependency on the cell. // a field load, even without deoptimization, because the property cannot be
if ((property_details.cell_type() == PropertyCellType::kConstant || // deleted or reconfigured to an accessor/interceptor property. Yet, if
property_details.cell_type() == PropertyCellType::kUndefined) && // deoptimization support is available, we can constant-fold certain global
(flags() & kDeoptimizationEnabled)) { // properties or at least lower them to field loads annotated with more
dependencies()->AssumePropertyCell(property_cell); // precise type feedback.
return Replace(node, property_cell_value); Type* property_cell_value_type =
} Type::Intersect(Type::Any(), Type::Tagged(), graph()->zone());
if (flags() & kDeoptimizationEnabled) {
// Record a code dependency on the cell if we can benefit from the
// additional feedback, or the global property is configurable (i.e.
// can be deleted or reconfigured to an accessor property).
if (property_details.cell_type() != PropertyCellType::kMutable ||
property_details.IsConfigurable()) {
dependencies()->AssumePropertyCell(property_cell);
}
// Load from constant type global property can benefit from representation // Load from constant/undefined global property can be constant-folded.
// (and map) feedback with deoptimization support (requires code dependency). if ((property_details.cell_type() == PropertyCellType::kConstant ||
if (property_details.cell_type() == PropertyCellType::kConstantType && property_details.cell_type() == PropertyCellType::kUndefined)) {
(flags() & kDeoptimizationEnabled)) { return Replace(node, property_cell_value);
dependencies()->AssumePropertyCell(property_cell);
// Compute proper type based on the current value in the cell.
Type* property_cell_value_type;
if (property_cell_value->IsSmi()) {
property_cell_value_type = Type::Intersect(
Type::SignedSmall(), Type::TaggedSigned(), graph()->zone());
} else if (property_cell_value->IsNumber()) {
property_cell_value_type = Type::Intersect(
Type::Number(), Type::TaggedPointer(), graph()->zone());
} else {
Handle<Map> property_cell_value_map(
Handle<HeapObject>::cast(property_cell_value)->map(), isolate());
property_cell_value_type =
Type::Class(property_cell_value_map, graph()->zone());
} }
Node* value = effect = graph()->NewNode(
simplified()->LoadField(
AccessBuilder::ForPropertyCellValue(property_cell_value_type)),
jsgraph()->Constant(property_cell), effect, control);
return Replace(node, value, effect);
}
// Load from non-configurable, data property on the global can be lowered to // Load from constant type cell can benefit from type feedback.
// a field load, even without deoptimization, because the property cannot be if (property_details.cell_type() == PropertyCellType::kConstantType) {
// deleted or reconfigured to an accessor/interceptor property. // Compute proper type based on the current value in the cell.
if (property_details.IsConfigurable()) { if (property_cell_value->IsSmi()) {
// With deoptimization support, we can lower loads even from configurable property_cell_value_type = Type::Intersect(
// data properties on the global object, by adding a code dependency on Type::SignedSmall(), Type::TaggedSigned(), graph()->zone());
// the cell. } else if (property_cell_value->IsNumber()) {
if (!(flags() & kDeoptimizationEnabled)) return NoChange(); property_cell_value_type = Type::Intersect(
dependencies()->AssumePropertyCell(property_cell); Type::Number(), Type::TaggedPointer(), graph()->zone());
} else {
Handle<Map> property_cell_value_map(
Handle<HeapObject>::cast(property_cell_value)->map(), isolate());
property_cell_value_type =
Type::Class(property_cell_value_map, graph()->zone());
}
}
} else if (property_details.IsConfigurable()) {
// Access to configurable global properties requires deoptimization support.
return NoChange();
} }
Node* value = effect = graph()->NewNode( Node* value = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForPropertyCellValue()), simplified()->LoadField(
AccessBuilder::ForPropertyCellValue(property_cell_value_type)),
jsgraph()->Constant(property_cell), effect, control); jsgraph()->Constant(property_cell), effect, control);
return Replace(node, value, effect); return Replace(node, value, effect);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment