// 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();
// 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();
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;
*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;
}
}
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,
// 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();
// 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();
// 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();
// 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();
// 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();