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_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
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 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 DCHECK(!value_reg.is(scratch)); | 386 DCHECK(!value_reg.is(scratch)); |
387 __ JumpIfSmi(value_reg, miss_label); | 387 __ JumpIfSmi(value_reg, miss_label); |
388 if (field_type->IsClass()) { | 388 if (field_type->IsClass()) { |
389 __ lw(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset)); | 389 __ lw(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset)); |
390 // Compare map directly within the Branch() functions. | 390 // Compare map directly within the Branch() functions. |
391 __ GetWeakValue(scratch, Map::WeakCellForMap(field_type->AsClass())); | 391 __ GetWeakValue(scratch, Map::WeakCellForMap(field_type->AsClass())); |
392 __ Branch(miss_label, ne, map_reg, Operand(scratch)); | 392 __ Branch(miss_label, ne, map_reg, Operand(scratch)); |
393 } | 393 } |
394 } | 394 } |
395 | 395 |
396 | |
397 Register PropertyHandlerCompiler::CheckPrototypes( | 396 Register PropertyHandlerCompiler::CheckPrototypes( |
398 Register object_reg, Register holder_reg, Register scratch1, | 397 Register object_reg, Register holder_reg, Register scratch1, |
399 Register scratch2, Handle<Name> name, Label* miss, PrototypeCheckType check, | 398 Register scratch2, Handle<Name> name, Label* miss, |
400 ReturnHolder return_what) { | 399 ReturnHolder return_what) { |
401 Handle<Map> receiver_map = map(); | 400 Handle<Map> receiver_map = map(); |
402 | 401 |
403 // Make sure there's no overlap between holder and object registers. | 402 // Make sure there's no overlap between holder and object registers. |
404 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 403 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
405 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && | 404 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && |
406 !scratch2.is(scratch1)); | 405 !scratch2.is(scratch1)); |
407 | 406 |
408 Handle<Cell> validity_cell = | 407 Handle<Cell> validity_cell = |
409 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | 408 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); |
410 if (!validity_cell.is_null()) { | 409 if (!validity_cell.is_null()) { |
411 DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); | 410 DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); |
412 __ li(scratch1, Operand(validity_cell)); | 411 __ li(scratch1, Operand(validity_cell)); |
413 __ lw(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); | 412 __ lw(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); |
414 __ Branch(miss, ne, scratch1, | 413 __ Branch(miss, ne, scratch1, |
415 Operand(Smi::FromInt(Map::kPrototypeChainValid))); | 414 Operand(Smi::FromInt(Map::kPrototypeChainValid))); |
416 } | 415 } |
417 | 416 |
418 // The prototype chain of primitives (and their JSValue wrappers) depends | |
419 // on the native context, which can't be guarded by validity cells. | |
420 // |object_reg| holds the native context specific prototype in this case; | |
421 // we need to check its map. | |
422 if (check == CHECK_ALL_MAPS) { | |
423 __ lw(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset)); | |
424 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); | |
425 __ GetWeakValue(scratch2, cell); | |
426 __ Branch(miss, ne, scratch1, Operand(scratch2)); | |
427 } | |
428 | |
429 // Keep track of the current object in register reg. | 417 // Keep track of the current object in register reg. |
430 Register reg = object_reg; | 418 Register reg = object_reg; |
431 int depth = 0; | 419 int depth = 0; |
432 | 420 |
433 Handle<JSObject> current = Handle<JSObject>::null(); | 421 Handle<JSObject> current = Handle<JSObject>::null(); |
434 if (receiver_map->IsJSGlobalObjectMap()) { | 422 if (receiver_map->IsJSGlobalObjectMap()) { |
435 current = isolate()->global_object(); | 423 current = isolate()->global_object(); |
436 } | 424 } |
437 | 425 |
438 Handle<JSObject> prototype = Handle<JSObject>::null(); | 426 Handle<Map> current_map(receiver_map->GetPrototypeChainRootMap(isolate()), |
439 Handle<Map> current_map = receiver_map; | 427 isolate()); |
440 Handle<Map> holder_map(holder()->map()); | 428 Handle<Map> holder_map(holder()->map()); |
441 // Traverse the prototype chain and check the maps in the prototype chain for | 429 // Traverse the prototype chain and check the maps in the prototype chain for |
442 // fast and global objects or do negative lookup for normal objects. | 430 // fast and global objects or do negative lookup for normal objects. |
443 while (!current_map.is_identical_to(holder_map)) { | 431 while (!current_map.is_identical_to(holder_map)) { |
444 ++depth; | 432 ++depth; |
445 | 433 |
446 prototype = handle(JSObject::cast(current_map->prototype())); | |
447 if (current_map->IsJSGlobalObjectMap()) { | 434 if (current_map->IsJSGlobalObjectMap()) { |
448 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), | 435 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), |
449 name, scratch2, miss); | 436 name, scratch2, miss); |
450 } else if (current_map->is_dictionary_map()) { | 437 } else if (current_map->is_dictionary_map()) { |
451 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. | 438 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. |
452 DCHECK(name->IsUniqueName()); | 439 DCHECK(name->IsUniqueName()); |
453 DCHECK(current.is_null() || | 440 DCHECK(current.is_null() || |
454 current->property_dictionary()->FindEntry(name) == | 441 current->property_dictionary()->FindEntry(name) == |
455 NameDictionary::kNotFound); | 442 NameDictionary::kNotFound); |
456 | 443 |
457 if (depth > 1) { | 444 if (depth > 1) { |
458 Handle<WeakCell> weak_cell = | 445 Handle<WeakCell> weak_cell = |
459 Map::GetOrCreatePrototypeWeakCell(current, isolate()); | 446 Map::GetOrCreatePrototypeWeakCell(current, isolate()); |
460 __ LoadWeakValue(reg, weak_cell, miss); | 447 __ LoadWeakValue(reg, weak_cell, miss); |
461 } | 448 } |
462 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, | 449 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, |
463 scratch2); | 450 scratch2); |
464 } | 451 } |
465 | 452 |
466 reg = holder_reg; // From now on the object will be in holder_reg. | 453 reg = holder_reg; // From now on the object will be in holder_reg. |
467 // Go to the next object in the prototype chain. | 454 // Go to the next object in the prototype chain. |
468 current = prototype; | 455 current = handle(JSObject::cast(current_map->prototype())); |
469 current_map = handle(current->map()); | 456 current_map = handle(current->map()); |
470 } | 457 } |
471 | 458 |
472 DCHECK(!current_map->IsJSGlobalProxyMap()); | 459 DCHECK(!current_map->IsJSGlobalProxyMap()); |
473 | 460 |
474 // Log the check depth. | 461 // Log the check depth. |
475 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 462 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
476 | 463 |
477 bool return_holder = return_what == RETURN_HOLDER; | 464 bool return_holder = return_what == RETURN_HOLDER; |
478 if (return_holder && depth != 0) { | 465 if (return_holder && depth != 0) { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 // Return the generated code. | 646 // Return the generated code. |
660 return GetCode(kind(), name); | 647 return GetCode(kind(), name); |
661 } | 648 } |
662 | 649 |
663 | 650 |
664 #undef __ | 651 #undef __ |
665 } // namespace internal | 652 } // namespace internal |
666 } // namespace v8 | 653 } // namespace v8 |
667 | 654 |
668 #endif // V8_TARGET_ARCH_MIPS | 655 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |