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 |