| OLD | NEW | 
|    1 // Copyright 2014 the V8 project authors. All rights reserved. |    1 // Copyright 2014 the V8 project authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #if V8_TARGET_ARCH_ARM64 |    5 #if V8_TARGET_ARCH_ARM64 | 
|    6  |    6  | 
|    7 #include "src/ic/handler-compiler.h" |    7 #include "src/ic/handler-compiler.h" | 
|    8  |    8  | 
|    9 #include "src/api-arguments.h" |    9 #include "src/api-arguments.h" | 
|   10 #include "src/field-type.h" |   10 #include "src/field-type.h" | 
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  430   DCHECK(!value_reg.is(scratch)); |  430   DCHECK(!value_reg.is(scratch)); | 
|  431   __ JumpIfSmi(value_reg, miss_label); |  431   __ JumpIfSmi(value_reg, miss_label); | 
|  432   if (field_type->IsClass()) { |  432   if (field_type->IsClass()) { | 
|  433     __ Ldr(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset)); |  433     __ Ldr(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset)); | 
|  434     __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()), |  434     __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()), | 
|  435                     scratch); |  435                     scratch); | 
|  436     __ B(ne, miss_label); |  436     __ B(ne, miss_label); | 
|  437   } |  437   } | 
|  438 } |  438 } | 
|  439  |  439  | 
|  440  |  | 
|  441 Register PropertyHandlerCompiler::CheckPrototypes( |  440 Register PropertyHandlerCompiler::CheckPrototypes( | 
|  442     Register object_reg, Register holder_reg, Register scratch1, |  441     Register object_reg, Register holder_reg, Register scratch1, | 
|  443     Register scratch2, Handle<Name> name, Label* miss, PrototypeCheckType check, |  442     Register scratch2, Handle<Name> name, Label* miss, | 
|  444     ReturnHolder return_what) { |  443     ReturnHolder return_what) { | 
|  445   Handle<Map> receiver_map = map(); |  444   Handle<Map> receiver_map = map(); | 
|  446  |  445  | 
|  447   // object_reg and holder_reg registers can alias. |  446   // object_reg and holder_reg registers can alias. | 
|  448   DCHECK(!AreAliased(object_reg, scratch1, scratch2)); |  447   DCHECK(!AreAliased(object_reg, scratch1, scratch2)); | 
|  449   DCHECK(!AreAliased(holder_reg, scratch1, scratch2)); |  448   DCHECK(!AreAliased(holder_reg, scratch1, scratch2)); | 
|  450  |  449  | 
|  451   Handle<Cell> validity_cell = |  450   Handle<Cell> validity_cell = | 
|  452       Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); |  451       Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | 
|  453   if (!validity_cell.is_null()) { |  452   if (!validity_cell.is_null()) { | 
|  454     DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); |  453     DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); | 
|  455     __ Mov(scratch1, Operand(validity_cell)); |  454     __ Mov(scratch1, Operand(validity_cell)); | 
|  456     __ Ldr(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); |  455     __ Ldr(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); | 
|  457     __ Cmp(scratch1, Operand(Smi::FromInt(Map::kPrototypeChainValid))); |  456     __ Cmp(scratch1, Operand(Smi::FromInt(Map::kPrototypeChainValid))); | 
|  458     __ B(ne, miss); |  457     __ B(ne, miss); | 
|  459   } |  458   } | 
|  460  |  459  | 
|  461   // The prototype chain of primitives (and their JSValue wrappers) depends |  | 
|  462   // on the native context, which can't be guarded by validity cells. |  | 
|  463   // |object_reg| holds the native context specific prototype in this case; |  | 
|  464   // we need to check its map. |  | 
|  465   if (check == CHECK_ALL_MAPS) { |  | 
|  466     __ Ldr(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset)); |  | 
|  467     Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |  | 
|  468     __ CmpWeakValue(scratch1, cell, scratch2); |  | 
|  469     __ B(ne, miss); |  | 
|  470   } |  | 
|  471  |  | 
|  472   // Keep track of the current object in register reg. |  460   // Keep track of the current object in register reg. | 
|  473   Register reg = object_reg; |  461   Register reg = object_reg; | 
|  474   int depth = 0; |  462   int depth = 0; | 
|  475  |  463  | 
|  476   Handle<JSObject> current = Handle<JSObject>::null(); |  464   Handle<JSObject> current = Handle<JSObject>::null(); | 
|  477   if (receiver_map->IsJSGlobalObjectMap()) { |  465   if (receiver_map->IsJSGlobalObjectMap()) { | 
|  478     current = isolate()->global_object(); |  466     current = isolate()->global_object(); | 
|  479   } |  467   } | 
|  480  |  468  | 
|  481   Handle<JSObject> prototype = Handle<JSObject>::null(); |  469   Handle<Map> current_map(receiver_map->GetPrototypeChainRootMap(isolate()), | 
|  482   Handle<Map> current_map = receiver_map; |  470                           isolate()); | 
|  483   Handle<Map> holder_map(holder()->map()); |  471   Handle<Map> holder_map(holder()->map()); | 
|  484   // Traverse the prototype chain and check the maps in the prototype chain for |  472   // Traverse the prototype chain and check the maps in the prototype chain for | 
|  485   // fast and global objects or do negative lookup for normal objects. |  473   // fast and global objects or do negative lookup for normal objects. | 
|  486   while (!current_map.is_identical_to(holder_map)) { |  474   while (!current_map.is_identical_to(holder_map)) { | 
|  487     ++depth; |  475     ++depth; | 
|  488  |  476  | 
|  489     prototype = handle(JSObject::cast(current_map->prototype())); |  | 
|  490     if (current_map->IsJSGlobalObjectMap()) { |  477     if (current_map->IsJSGlobalObjectMap()) { | 
|  491       GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), |  478       GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), | 
|  492                                 name, scratch2, miss); |  479                                 name, scratch2, miss); | 
|  493     } else if (current_map->is_dictionary_map()) { |  480     } else if (current_map->is_dictionary_map()) { | 
|  494       DCHECK(!current_map->IsJSGlobalProxyMap());  // Proxy maps are fast. |  481       DCHECK(!current_map->IsJSGlobalProxyMap());  // Proxy maps are fast. | 
|  495       DCHECK(name->IsUniqueName()); |  482       DCHECK(name->IsUniqueName()); | 
|  496       DCHECK(current.is_null() || (current->property_dictionary()->FindEntry( |  483       DCHECK(current.is_null() || (current->property_dictionary()->FindEntry( | 
|  497                                        name) == NameDictionary::kNotFound)); |  484                                        name) == NameDictionary::kNotFound)); | 
|  498  |  485  | 
|  499       if (depth > 1) { |  486       if (depth > 1) { | 
|  500         Handle<WeakCell> weak_cell = |  487         Handle<WeakCell> weak_cell = | 
|  501             Map::GetOrCreatePrototypeWeakCell(current, isolate()); |  488             Map::GetOrCreatePrototypeWeakCell(current, isolate()); | 
|  502         __ LoadWeakValue(reg, weak_cell, miss); |  489         __ LoadWeakValue(reg, weak_cell, miss); | 
|  503       } |  490       } | 
|  504       GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, |  491       GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, | 
|  505                                        scratch2); |  492                                        scratch2); | 
|  506     } |  493     } | 
|  507  |  494  | 
|  508     reg = holder_reg;  // From now on the object will be in holder_reg. |  495     reg = holder_reg;  // From now on the object will be in holder_reg. | 
|  509     // Go to the next object in the prototype chain. |  496     // Go to the next object in the prototype chain. | 
|  510     current = prototype; |  497     current = handle(JSObject::cast(current_map->prototype())); | 
|  511     current_map = handle(current->map()); |  498     current_map = handle(current->map()); | 
|  512   } |  499   } | 
|  513  |  500  | 
|  514   DCHECK(!current_map->IsJSGlobalProxyMap()); |  501   DCHECK(!current_map->IsJSGlobalProxyMap()); | 
|  515  |  502  | 
|  516   // Log the check depth. |  503   // Log the check depth. | 
|  517   LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |  504   LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 
|  518  |  505  | 
|  519   bool return_holder = return_what == RETURN_HOLDER; |  506   bool return_holder = return_what == RETURN_HOLDER; | 
|  520   if (return_holder && depth != 0) { |  507   if (return_holder && depth != 0) { | 
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  670   // Return the generated code. |  657   // Return the generated code. | 
|  671   return GetCode(kind(), name); |  658   return GetCode(kind(), name); | 
|  672 } |  659 } | 
|  673  |  660  | 
|  674  |  661  | 
|  675 #undef __ |  662 #undef __ | 
|  676 }  // namespace internal |  663 }  // namespace internal | 
|  677 }  // namespace v8 |  664 }  // namespace v8 | 
|  678  |  665  | 
|  679 #endif  // V8_TARGET_ARCH_IA32 |  666 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW |