 Chromium Code Reviews
 Chromium Code Reviews Issue 1559033:
  Reapply load ICs for nonexistent properties....  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
    
  
    Issue 1559033:
  Reapply load ICs for nonexistent properties....  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/| OLD | NEW | 
|---|---|
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright | 
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. | 
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above | 
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following | 
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided | 
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 compiler->CompileRegular(masm, | 593 compiler->CompileRegular(masm, | 
| 594 receiver, | 594 receiver, | 
| 595 reg, | 595 reg, | 
| 596 scratch2, | 596 scratch2, | 
| 597 holder, | 597 holder, | 
| 598 miss); | 598 miss); | 
| 599 } | 599 } | 
| 600 } | 600 } | 
| 601 | 601 | 
| 602 | 602 | 
| 603 // Generate code to check that a global property cell is empty. Create | |
| 604 // the property cell at compilation time if no cell exists for the | |
| 605 // property. | |
| 606 static Object* GenerateCheckPropertyCell(MacroAssembler* masm, | |
| 607 GlobalObject* global, | |
| 608 String* name, | |
| 609 Register scratch, | |
| 610 Label* miss) { | |
| 611 Object* probe = global->EnsurePropertyCell(name); | |
| 612 if (probe->IsFailure()) return probe; | |
| 613 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | |
| 614 ASSERT(cell->value()->IsTheHole()); | |
| 615 __ mov(scratch, Operand(Handle<Object>(cell))); | |
| 616 __ ldr(scratch, | |
| 617 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | |
| 618 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | |
| 619 __ cmp(scratch, ip); | |
| 620 __ b(ne, miss); | |
| 621 return cell; | |
| 622 } | |
| 623 | |
| 624 | |
| 603 #undef __ | 625 #undef __ | 
| 604 #define __ ACCESS_MASM(masm()) | 626 #define __ ACCESS_MASM(masm()) | 
| 605 | 627 | 
| 606 | 628 | 
| 607 Register StubCompiler::CheckPrototypes(JSObject* object, | 629 Register StubCompiler::CheckPrototypes(JSObject* object, | 
| 608 Register object_reg, | 630 Register object_reg, | 
| 609 JSObject* holder, | 631 JSObject* holder, | 
| 610 Register holder_reg, | 632 Register holder_reg, | 
| 611 Register scratch, | 633 Register scratch, | 
| 612 String* name, | 634 String* name, | 
| 613 int save_at_depth, | 635 int save_at_depth, | 
| 614 Label* miss) { | 636 Label* miss) { | 
| 615 // TODO(602): support object saving. | 637 // TODO(602): support object saving. | 
| 616 ASSERT(save_at_depth == kInvalidProtoDepth); | 638 ASSERT(save_at_depth == kInvalidProtoDepth); | 
| 617 | 639 | 
| 618 // Check that the maps haven't changed. | 640 // Check that the maps haven't changed. | 
| 619 Register result = | 641 Register result = | 
| 620 masm()->CheckMaps(object, object_reg, holder, holder_reg, scratch, miss); | 642 masm()->CheckMaps(object, object_reg, holder, holder_reg, scratch, miss); | 
| 621 | 643 | 
| 622 // If we've skipped any global objects, it's not enough to verify | 644 // If we've skipped any global objects, it's not enough to verify | 
| 623 // that their maps haven't changed. | 645 // that their maps haven't changed. We also need to check that the | 
| 646 // property cell for the property is still empty. | |
| 624 while (object != holder) { | 647 while (object != holder) { | 
| 625 if (object->IsGlobalObject()) { | 648 if (object->IsGlobalObject()) { | 
| 626 GlobalObject* global = GlobalObject::cast(object); | 649 Object* cell = GenerateCheckPropertyCell(masm(), | 
| 627 Object* probe = global->EnsurePropertyCell(name); | 650 GlobalObject::cast(object), | 
| 628 if (probe->IsFailure()) { | 651 name, | 
| 629 set_failure(Failure::cast(probe)); | 652 scratch, | 
| 653 miss); | |
| 654 if (cell->IsFailure()) { | |
| 655 set_failure(Failure::cast(cell)); | |
| 630 return result; | 656 return result; | 
| 631 } | 657 } | 
| 632 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | |
| 633 ASSERT(cell->value()->IsTheHole()); | |
| 634 __ mov(scratch, Operand(Handle<Object>(cell))); | |
| 635 __ ldr(scratch, | |
| 636 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | |
| 637 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | |
| 638 __ cmp(scratch, ip); | |
| 639 __ b(ne, miss); | |
| 640 } | 658 } | 
| 641 object = JSObject::cast(object->GetPrototype()); | 659 object = JSObject::cast(object->GetPrototype()); | 
| 642 } | 660 } | 
| 643 | 661 | 
| 644 // Return the register containing the holder. | 662 // Return the register containing the holder. | 
| 645 return result; | 663 return result; | 
| 646 } | 664 } | 
| 647 | 665 | 
| 648 | 666 | 
| 649 void StubCompiler::GenerateLoadField(JSObject* object, | 667 void StubCompiler::GenerateLoadField(JSObject* object, | 
| (...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1382 __ bind(&miss); | 1400 __ bind(&miss); | 
| 1383 __ IncrementCounter(&Counters::named_store_global_inline_miss, 1, r4, r3); | 1401 __ IncrementCounter(&Counters::named_store_global_inline_miss, 1, r4, r3); | 
| 1384 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 1402 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 
| 1385 __ Jump(ic, RelocInfo::CODE_TARGET); | 1403 __ Jump(ic, RelocInfo::CODE_TARGET); | 
| 1386 | 1404 | 
| 1387 // Return the generated code. | 1405 // Return the generated code. | 
| 1388 return GetCode(NORMAL, name); | 1406 return GetCode(NORMAL, name); | 
| 1389 } | 1407 } | 
| 1390 | 1408 | 
| 1391 | 1409 | 
| 1410 Object* LoadStubCompiler::CompileLoadNonexistent(String* name, | |
| 1411 JSObject* object, | |
| 1412 JSObject* last) { | |
| 1413 // ----------- S t a t e ------------- | |
| 1414 // -- r2 : name | |
| 1415 // -- lr : return address | |
| 1416 // -- [sp] : receiver | |
| 1417 // ----------------------------------- | |
| 1418 Label miss; | |
| 1419 | |
| 1420 // Load receiver. | |
| 1421 __ ldr(r0, MemOperand(sp, 0)); | |
| 1422 | |
| 1423 // Check the maps of the full prototype chain. | |
| 1424 CheckPrototypes(object, r0, last, r3, r1, name, &miss); | |
| 1425 | |
| 1426 // If the last object in the prototype chain is a global object, | |
| 1427 // check that the global property cell is empty. | |
| 1428 if (last->IsGlobalObject()) { | |
| 1429 Object* cell = GenerateCheckPropertyCell(masm(), | |
| 1430 GlobalObject::cast(last), | |
| 1431 name, | |
| 1432 r1, | |
| 1433 &miss); | |
| 1434 if (cell->IsFailure()) return cell; | |
| 1435 } | |
| 1436 | |
| 1437 // Return undefined if maps of the full prototype chain is still the | |
| 
Erik Corry
2010/04/15 10:28:44
maps ... is -> maps ... are
 | |
| 1438 // same and no global property with this name contains a value. | |
| 1439 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | |
| 1440 __ Ret(); | |
| 1441 | |
| 1442 __ bind(&miss); | |
| 1443 GenerateLoadMiss(masm(), Code::LOAD_IC); | |
| 1444 | |
| 1445 // Return the generated code. | |
| 1446 return GetCode(NONEXISTENT, Heap::empty_string()); | |
| 1447 } | |
| 1448 | |
| 1449 | |
| 1392 Object* LoadStubCompiler::CompileLoadField(JSObject* object, | 1450 Object* LoadStubCompiler::CompileLoadField(JSObject* object, | 
| 1393 JSObject* holder, | 1451 JSObject* holder, | 
| 1394 int index, | 1452 int index, | 
| 1395 String* name) { | 1453 String* name) { | 
| 1396 // ----------- S t a t e ------------- | 1454 // ----------- S t a t e ------------- | 
| 1397 // -- r2 : name | 1455 // -- r2 : name | 
| 1398 // -- lr : return address | 1456 // -- lr : return address | 
| 1399 // -- [sp] : receiver | 1457 // -- [sp] : receiver | 
| 1400 // ----------------------------------- | 1458 // ----------------------------------- | 
| 1401 Label miss; | 1459 Label miss; | 
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1893 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 1951 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 
| 1894 | 1952 | 
| 1895 // Return the generated code. | 1953 // Return the generated code. | 
| 1896 return GetCode(); | 1954 return GetCode(); | 
| 1897 } | 1955 } | 
| 1898 | 1956 | 
| 1899 | 1957 | 
| 1900 #undef __ | 1958 #undef __ | 
| 1901 | 1959 | 
| 1902 } } // namespace v8::internal | 1960 } } // namespace v8::internal | 
| OLD | NEW |