| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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_S390 | 5 #if V8_TARGET_ARCH_S390 |
| 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 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 if (field_type->IsClass()) { | 378 if (field_type->IsClass()) { |
| 379 __ LoadP(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset)); | 379 __ LoadP(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset)); |
| 380 __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()), | 380 __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()), |
| 381 scratch); | 381 scratch); |
| 382 __ bne(miss_label); | 382 __ bne(miss_label); |
| 383 } | 383 } |
| 384 } | 384 } |
| 385 | 385 |
| 386 Register PropertyHandlerCompiler::CheckPrototypes( | 386 Register PropertyHandlerCompiler::CheckPrototypes( |
| 387 Register object_reg, Register holder_reg, Register scratch1, | 387 Register object_reg, Register holder_reg, Register scratch1, |
| 388 Register scratch2, Handle<Name> name, Label* miss, PrototypeCheckType check, | 388 Register scratch2, Handle<Name> name, Label* miss, |
| 389 ReturnHolder return_what) { | 389 ReturnHolder return_what) { |
| 390 Handle<Map> receiver_map = map(); | 390 Handle<Map> receiver_map = map(); |
| 391 | 391 |
| 392 // Make sure there's no overlap between holder and object registers. | 392 // Make sure there's no overlap between holder and object registers. |
| 393 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 393 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
| 394 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && | 394 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && |
| 395 !scratch2.is(scratch1)); | 395 !scratch2.is(scratch1)); |
| 396 | 396 |
| 397 Handle<Cell> validity_cell = | 397 Handle<Cell> validity_cell = |
| 398 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | 398 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); |
| 399 if (!validity_cell.is_null()) { | 399 if (!validity_cell.is_null()) { |
| 400 DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); | 400 DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); |
| 401 __ mov(scratch1, Operand(validity_cell)); | 401 __ mov(scratch1, Operand(validity_cell)); |
| 402 __ LoadP(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); | 402 __ LoadP(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); |
| 403 __ CmpSmiLiteral(scratch1, Smi::FromInt(Map::kPrototypeChainValid), r0); | 403 __ CmpSmiLiteral(scratch1, Smi::FromInt(Map::kPrototypeChainValid), r0); |
| 404 __ bne(miss); | 404 __ bne(miss); |
| 405 } | 405 } |
| 406 | 406 |
| 407 // The prototype chain of primitives (and their JSValue wrappers) depends | |
| 408 // on the native context, which can't be guarded by validity cells. | |
| 409 // |object_reg| holds the native context specific prototype in this case; | |
| 410 // we need to check its map. | |
| 411 if (check == CHECK_ALL_MAPS) { | |
| 412 __ LoadP(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset)); | |
| 413 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); | |
| 414 __ CmpWeakValue(scratch1, cell, scratch2); | |
| 415 __ b(ne, miss); | |
| 416 } | |
| 417 | |
| 418 // Keep track of the current object in register reg. | 407 // Keep track of the current object in register reg. |
| 419 Register reg = object_reg; | 408 Register reg = object_reg; |
| 420 int depth = 0; | 409 int depth = 0; |
| 421 | 410 |
| 422 Handle<JSObject> current = Handle<JSObject>::null(); | 411 Handle<JSObject> current = Handle<JSObject>::null(); |
| 423 if (receiver_map->IsJSGlobalObjectMap()) { | 412 if (receiver_map->IsJSGlobalObjectMap()) { |
| 424 current = isolate()->global_object(); | 413 current = isolate()->global_object(); |
| 425 } | 414 } |
| 426 | 415 |
| 427 Handle<JSObject> prototype = Handle<JSObject>::null(); | 416 Handle<Map> current_map(receiver_map->GetPrototypeChainRootMap(isolate()), |
| 428 Handle<Map> current_map = receiver_map; | 417 isolate()); |
| 429 Handle<Map> holder_map(holder()->map()); | 418 Handle<Map> holder_map(holder()->map()); |
| 430 // Traverse the prototype chain and check the maps in the prototype chain for | 419 // Traverse the prototype chain and check the maps in the prototype chain for |
| 431 // fast and global objects or do negative lookup for normal objects. | 420 // fast and global objects or do negative lookup for normal objects. |
| 432 while (!current_map.is_identical_to(holder_map)) { | 421 while (!current_map.is_identical_to(holder_map)) { |
| 433 ++depth; | 422 ++depth; |
| 434 | 423 |
| 435 prototype = handle(JSObject::cast(current_map->prototype())); | |
| 436 if (current_map->IsJSGlobalObjectMap()) { | 424 if (current_map->IsJSGlobalObjectMap()) { |
| 437 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), | 425 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), |
| 438 name, scratch2, miss); | 426 name, scratch2, miss); |
| 439 } else if (current_map->is_dictionary_map()) { | 427 } else if (current_map->is_dictionary_map()) { |
| 440 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. | 428 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. |
| 441 DCHECK(name->IsUniqueName()); | 429 DCHECK(name->IsUniqueName()); |
| 442 DCHECK(current.is_null() || | 430 DCHECK(current.is_null() || |
| 443 current->property_dictionary()->FindEntry(name) == | 431 current->property_dictionary()->FindEntry(name) == |
| 444 NameDictionary::kNotFound); | 432 NameDictionary::kNotFound); |
| 445 | 433 |
| 446 if (depth > 1) { | 434 if (depth > 1) { |
| 447 Handle<WeakCell> weak_cell = | 435 Handle<WeakCell> weak_cell = |
| 448 Map::GetOrCreatePrototypeWeakCell(current, isolate()); | 436 Map::GetOrCreatePrototypeWeakCell(current, isolate()); |
| 449 __ LoadWeakValue(reg, weak_cell, miss); | 437 __ LoadWeakValue(reg, weak_cell, miss); |
| 450 } | 438 } |
| 451 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, | 439 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, |
| 452 scratch2); | 440 scratch2); |
| 453 } | 441 } |
| 454 | 442 |
| 455 reg = holder_reg; // From now on the object will be in holder_reg. | 443 reg = holder_reg; // From now on the object will be in holder_reg. |
| 456 // Go to the next object in the prototype chain. | 444 // Go to the next object in the prototype chain. |
| 457 current = prototype; | 445 current = handle(JSObject::cast(current_map->prototype())); |
| 458 current_map = handle(current->map()); | 446 current_map = handle(current->map()); |
| 459 } | 447 } |
| 460 | 448 |
| 461 DCHECK(!current_map->IsJSGlobalProxyMap()); | 449 DCHECK(!current_map->IsJSGlobalProxyMap()); |
| 462 | 450 |
| 463 // Log the check depth. | 451 // Log the check depth. |
| 464 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 452 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 465 | 453 |
| 466 bool return_holder = return_what == RETURN_HOLDER; | 454 bool return_holder = return_what == RETURN_HOLDER; |
| 467 if (return_holder && depth != 0) { | 455 if (return_holder && depth != 0) { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 | 627 |
| 640 // Return the generated code. | 628 // Return the generated code. |
| 641 return GetCode(kind(), name); | 629 return GetCode(kind(), name); |
| 642 } | 630 } |
| 643 | 631 |
| 644 #undef __ | 632 #undef __ |
| 645 } // namespace internal | 633 } // namespace internal |
| 646 } // namespace v8 | 634 } // namespace v8 |
| 647 | 635 |
| 648 #endif // V8_TARGET_ARCH_ARM | 636 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |