| Index: src/compiler/js-call-reducer.cc
|
| diff --git a/src/compiler/js-call-reducer.cc b/src/compiler/js-call-reducer.cc
|
| index f0febc4d26ac61f2fecc05a409b3f7c7b158e855..2be5c161f58d59d6c80f9dfecfcdef3511f10380 100644
|
| --- a/src/compiler/js-call-reducer.cc
|
| +++ b/src/compiler/js-call-reducer.cc
|
| @@ -327,39 +327,41 @@ JSCallReducer::HolderLookup JSCallReducer::LookupHolder(
|
| return kHolderNotFound;
|
| }
|
|
|
| -// ES6 section B.2.2.1.1 get Object.prototype.__proto__
|
| -Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) {
|
| - DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
|
| - Node* receiver = NodeProperties::GetValueInput(node, 1);
|
| +Reduction JSCallReducer::ReduceObjectGetPrototype(Node* node, Node* object) {
|
| Node* effect = NodeProperties::GetEffectInput(node);
|
|
|
| - // Try to determine the {receiver} map.
|
| - ZoneHandleSet<Map> receiver_maps;
|
| + // Try to determine the {object} map.
|
| + ZoneHandleSet<Map> object_maps;
|
| NodeProperties::InferReceiverMapsResult result =
|
| - NodeProperties::InferReceiverMaps(receiver, effect, &receiver_maps);
|
| + NodeProperties::InferReceiverMaps(object, effect, &object_maps);
|
| if (result != NodeProperties::kNoReceiverMaps) {
|
| Handle<Map> candidate_map(
|
| - receiver_maps[0]->GetPrototypeChainRootMap(isolate()));
|
| + object_maps[0]->GetPrototypeChainRootMap(isolate()));
|
| Handle<Object> candidate_prototype(candidate_map->prototype(), isolate());
|
|
|
| + // We cannot deal with primitives here.
|
| + if (candidate_map->IsPrimitiveMap()) return NoChange();
|
| +
|
| // Check if we can constant-fold the {candidate_prototype}.
|
| - for (size_t i = 0; i < receiver_maps.size(); ++i) {
|
| - Handle<Map> const receiver_map(
|
| - receiver_maps[i]->GetPrototypeChainRootMap(isolate()));
|
| - if (receiver_map->IsJSProxyMap() ||
|
| - receiver_map->has_hidden_prototype() ||
|
| - receiver_map->is_access_check_needed() ||
|
| - receiver_map->prototype() != *candidate_prototype) {
|
| + for (size_t i = 0; i < object_maps.size(); ++i) {
|
| + Handle<Map> const object_map(
|
| + object_maps[i]->GetPrototypeChainRootMap(isolate()));
|
| + if (object_map->IsSpecialReceiverMap() ||
|
| + object_map->has_hidden_prototype() ||
|
| + object_map->prototype() != *candidate_prototype) {
|
| + // We exclude special receivers, like JSProxy or API objects that
|
| + // might require access checks here; we also don't want to deal
|
| + // with hidden prototypes at this point.
|
| return NoChange();
|
| }
|
| if (result == NodeProperties::kUnreliableReceiverMaps &&
|
| - !receiver_map->is_stable()) {
|
| + !object_map->is_stable()) {
|
| return NoChange();
|
| }
|
| }
|
| if (result == NodeProperties::kUnreliableReceiverMaps) {
|
| - for (size_t i = 0; i < receiver_maps.size(); ++i) {
|
| - dependencies()->AssumeMapStable(receiver_maps[i]);
|
| + for (size_t i = 0; i < object_maps.size(); ++i) {
|
| + dependencies()->AssumeMapStable(object_maps[i]);
|
| }
|
| }
|
| Node* value = jsgraph()->Constant(candidate_prototype);
|
| @@ -370,6 +372,31 @@ Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) {
|
| return NoChange();
|
| }
|
|
|
| +// ES6 section 19.1.2.11 Object.getPrototypeOf ( O )
|
| +Reduction JSCallReducer::ReduceObjectGetPrototypeOf(Node* node) {
|
| + DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
|
| + Node* object = (node->op()->ValueInputCount() >= 3)
|
| + ? NodeProperties::GetValueInput(node, 2)
|
| + : jsgraph()->UndefinedConstant();
|
| + return ReduceObjectGetPrototype(node, object);
|
| +}
|
| +
|
| +// ES6 section B.2.2.1.1 get Object.prototype.__proto__
|
| +Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) {
|
| + DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
|
| + Node* receiver = NodeProperties::GetValueInput(node, 1);
|
| + return ReduceObjectGetPrototype(node, receiver);
|
| +}
|
| +
|
| +// ES6 section 26.1.7 Reflect.getPrototypeOf ( target )
|
| +Reduction JSCallReducer::ReduceReflectGetPrototypeOf(Node* node) {
|
| + DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
|
| + Node* target = (node->op()->ValueInputCount() >= 3)
|
| + ? NodeProperties::GetValueInput(node, 2)
|
| + : jsgraph()->UndefinedConstant();
|
| + return ReduceObjectGetPrototype(node, target);
|
| +}
|
| +
|
| Reduction JSCallReducer::ReduceCallApiFunction(
|
| Node* node, Node* target,
|
| Handle<FunctionTemplateInfo> function_template_info) {
|
| @@ -570,8 +597,12 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
|
| return ReduceFunctionPrototypeHasInstance(node);
|
| case Builtins::kNumberConstructor:
|
| return ReduceNumberConstructor(node);
|
| + case Builtins::kObjectGetPrototypeOf:
|
| + return ReduceObjectGetPrototypeOf(node);
|
| case Builtins::kObjectPrototypeGetProto:
|
| return ReduceObjectPrototypeGetProto(node);
|
| + case Builtins::kReflectGetPrototypeOf:
|
| + return ReduceReflectGetPrototypeOf(node);
|
| default:
|
| break;
|
| }
|
|
|