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 |