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:
ulan 2015-01-29 09:18:41 -08:00 committed by Commit bot
parent 350cbaabfd
commit b98f27f592
9 changed files with 71 additions and 24 deletions

View File

@ -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();

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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();