Load API holder from prototype chain instead embedding it in handler.
BUG=v8:3629 LOG=N Review URL: https://codereview.chromium.org/873723005 Cr-Commit-Position: refs/heads/master@{#26331}
This commit is contained in:
parent
350cbaabfd
commit
b98f27f592
@ -266,14 +266,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
|
||||
// Put holder in place.
|
||||
CallOptimization::HolderLookup holder_lookup;
|
||||
Handle<JSObject> api_holder =
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
|
||||
int holder_depth = 0;
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
|
||||
&holder_depth);
|
||||
switch (holder_lookup) {
|
||||
case CallOptimization::kHolderIsReceiver:
|
||||
__ Move(holder, receiver);
|
||||
break;
|
||||
case CallOptimization::kHolderFound:
|
||||
__ Move(holder, api_holder);
|
||||
__ ldr(holder, FieldMemOperand(receiver, HeapObject::kMapOffset));
|
||||
__ ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
|
||||
for (int i = 1; i < holder_depth; i++) {
|
||||
__ ldr(holder, FieldMemOperand(holder, HeapObject::kMapOffset));
|
||||
__ ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
|
||||
}
|
||||
break;
|
||||
case CallOptimization::kHolderNotFound:
|
||||
UNREACHABLE();
|
||||
|
@ -178,14 +178,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
|
||||
// Put holder in place.
|
||||
CallOptimization::HolderLookup holder_lookup;
|
||||
Handle<JSObject> api_holder =
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
|
||||
int holder_depth = 0;
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
|
||||
&holder_depth);
|
||||
switch (holder_lookup) {
|
||||
case CallOptimization::kHolderIsReceiver:
|
||||
__ Mov(holder, receiver);
|
||||
break;
|
||||
case CallOptimization::kHolderFound:
|
||||
__ LoadObject(holder, api_holder);
|
||||
__ Ldr(holder, FieldMemOperand(receiver, HeapObject::kMapOffset));
|
||||
__ Ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
|
||||
for (int i = 1; i < holder_depth; i++) {
|
||||
__ Ldr(holder, FieldMemOperand(holder, HeapObject::kMapOffset));
|
||||
__ Ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
|
||||
}
|
||||
break;
|
||||
case CallOptimization::kHolderNotFound:
|
||||
UNREACHABLE();
|
||||
|
@ -16,7 +16,8 @@ CallOptimization::CallOptimization(Handle<JSFunction> function) {
|
||||
|
||||
|
||||
Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
|
||||
Handle<Map> object_map, HolderLookup* holder_lookup) const {
|
||||
Handle<Map> object_map, HolderLookup* holder_lookup,
|
||||
int* holder_depth_in_prototype_chain) const {
|
||||
DCHECK(is_simple_api_call());
|
||||
if (!object_map->IsJSObjectMap()) {
|
||||
*holder_lookup = kHolderNotFound;
|
||||
@ -27,13 +28,16 @@ Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
|
||||
*holder_lookup = kHolderIsReceiver;
|
||||
return Handle<JSObject>::null();
|
||||
}
|
||||
while (true) {
|
||||
for (int depth = 1; true; depth++) {
|
||||
if (!object_map->prototype()->IsJSObject()) break;
|
||||
Handle<JSObject> prototype(JSObject::cast(object_map->prototype()));
|
||||
if (!prototype->map()->is_hidden_prototype()) break;
|
||||
object_map = handle(prototype->map());
|
||||
if (expected_receiver_type_->IsTemplateFor(*object_map)) {
|
||||
*holder_lookup = kHolderFound;
|
||||
if (holder_depth_in_prototype_chain != NULL) {
|
||||
*holder_depth_in_prototype_chain = depth;
|
||||
}
|
||||
return prototype;
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,8 @@ class CallOptimization BASE_EMBEDDED {
|
||||
|
||||
enum HolderLookup { kHolderNotFound, kHolderIsReceiver, kHolderFound };
|
||||
Handle<JSObject> LookupHolderOfExpectedType(
|
||||
Handle<Map> receiver_map, HolderLookup* holder_lookup) const;
|
||||
Handle<Map> receiver_map, HolderLookup* holder_lookup,
|
||||
int* holder_depth_in_prototype_chain = NULL) const;
|
||||
|
||||
// Check if the api holder is between the receiver and the holder.
|
||||
bool IsCompatibleReceiver(Handle<Object> receiver,
|
||||
|
@ -175,14 +175,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
|
||||
// Put holder in place.
|
||||
CallOptimization::HolderLookup holder_lookup;
|
||||
Handle<JSObject> api_holder =
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
|
||||
int holder_depth = 0;
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
|
||||
&holder_depth);
|
||||
switch (holder_lookup) {
|
||||
case CallOptimization::kHolderIsReceiver:
|
||||
__ Move(holder, receiver);
|
||||
break;
|
||||
case CallOptimization::kHolderFound:
|
||||
__ LoadHeapObject(holder, api_holder);
|
||||
__ mov(holder, FieldOperand(receiver, HeapObject::kMapOffset));
|
||||
__ mov(holder, FieldOperand(holder, Map::kPrototypeOffset));
|
||||
for (int i = 1; i < holder_depth; i++) {
|
||||
__ mov(holder, FieldOperand(holder, HeapObject::kMapOffset));
|
||||
__ mov(holder, FieldOperand(holder, Map::kPrototypeOffset));
|
||||
}
|
||||
break;
|
||||
case CallOptimization::kHolderNotFound:
|
||||
UNREACHABLE();
|
||||
|
@ -259,14 +259,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
|
||||
// Put holder in place.
|
||||
CallOptimization::HolderLookup holder_lookup;
|
||||
Handle<JSObject> api_holder =
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
|
||||
int holder_depth = 0;
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
|
||||
&holder_depth);
|
||||
switch (holder_lookup) {
|
||||
case CallOptimization::kHolderIsReceiver:
|
||||
__ Move(holder, receiver);
|
||||
break;
|
||||
case CallOptimization::kHolderFound:
|
||||
__ li(holder, api_holder);
|
||||
__ lw(holder, FieldMemOperand(receiver, HeapObject::kMapOffset));
|
||||
__ lw(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
|
||||
for (int i = 1; i < holder_depth; i++) {
|
||||
__ lw(holder, FieldMemOperand(holder, HeapObject::kMapOffset));
|
||||
__ lw(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
|
||||
}
|
||||
break;
|
||||
case CallOptimization::kHolderNotFound:
|
||||
UNREACHABLE();
|
||||
|
@ -260,14 +260,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
|
||||
// Put holder in place.
|
||||
CallOptimization::HolderLookup holder_lookup;
|
||||
Handle<JSObject> api_holder =
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
|
||||
int holder_depth = 0;
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
|
||||
&holder_depth);
|
||||
switch (holder_lookup) {
|
||||
case CallOptimization::kHolderIsReceiver:
|
||||
__ Move(holder, receiver);
|
||||
break;
|
||||
case CallOptimization::kHolderFound:
|
||||
__ li(holder, api_holder);
|
||||
__ ld(holder, FieldMemOperand(receiver, HeapObject::kMapOffset));
|
||||
__ ld(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
|
||||
for (int i = 1; i < holder_depth; i++) {
|
||||
__ ld(holder, FieldMemOperand(holder, HeapObject::kMapOffset));
|
||||
__ ld(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
|
||||
}
|
||||
break;
|
||||
case CallOptimization::kHolderNotFound:
|
||||
UNREACHABLE();
|
||||
|
@ -161,14 +161,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
|
||||
// Put holder in place.
|
||||
CallOptimization::HolderLookup holder_lookup;
|
||||
Handle<JSObject> api_holder =
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
|
||||
int holder_depth = 0;
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
|
||||
&holder_depth);
|
||||
switch (holder_lookup) {
|
||||
case CallOptimization::kHolderIsReceiver:
|
||||
__ Move(holder, receiver);
|
||||
break;
|
||||
case CallOptimization::kHolderFound:
|
||||
__ Move(holder, api_holder);
|
||||
__ movp(holder, FieldOperand(receiver, HeapObject::kMapOffset));
|
||||
__ movp(holder, FieldOperand(holder, Map::kPrototypeOffset));
|
||||
for (int i = 1; i < holder_depth; i++) {
|
||||
__ movp(holder, FieldOperand(holder, HeapObject::kMapOffset));
|
||||
__ movp(holder, FieldOperand(holder, Map::kPrototypeOffset));
|
||||
}
|
||||
break;
|
||||
case CallOptimization::kHolderNotFound:
|
||||
UNREACHABLE();
|
||||
|
@ -175,14 +175,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
|
||||
// Put holder in place.
|
||||
CallOptimization::HolderLookup holder_lookup;
|
||||
Handle<JSObject> api_holder =
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
|
||||
int holder_depth = 0;
|
||||
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
|
||||
&holder_depth);
|
||||
switch (holder_lookup) {
|
||||
case CallOptimization::kHolderIsReceiver:
|
||||
__ Move(holder, receiver);
|
||||
break;
|
||||
case CallOptimization::kHolderFound:
|
||||
__ LoadHeapObject(holder, api_holder);
|
||||
__ mov(holder, FieldOperand(receiver, HeapObject::kMapOffset));
|
||||
__ mov(holder, FieldOperand(holder, Map::kPrototypeOffset));
|
||||
for (int i = 1; i < holder_depth; i++) {
|
||||
__ mov(holder, FieldOperand(holder, HeapObject::kMapOffset));
|
||||
__ mov(holder, FieldOperand(holder, Map::kPrototypeOffset));
|
||||
}
|
||||
break;
|
||||
case CallOptimization::kHolderNotFound:
|
||||
UNREACHABLE();
|
||||
|
Loading…
Reference in New Issue
Block a user