OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
507 if (entry != StringDictionary::kNotFound) { | 507 if (entry != StringDictionary::kNotFound) { |
508 // If we have a global object set the cell to the hole. | 508 // If we have a global object set the cell to the hole. |
509 if (IsGlobalObject()) { | 509 if (IsGlobalObject()) { |
510 PropertyDetails details = dictionary->DetailsAt(entry); | 510 PropertyDetails details = dictionary->DetailsAt(entry); |
511 if (details.IsDontDelete()) { | 511 if (details.IsDontDelete()) { |
512 if (mode != FORCE_DELETION) return GetHeap()->false_value(); | 512 if (mode != FORCE_DELETION) return GetHeap()->false_value(); |
513 // When forced to delete global properties, we have to make a | 513 // When forced to delete global properties, we have to make a |
514 // map change to invalidate any ICs that think they can load | 514 // map change to invalidate any ICs that think they can load |
515 // from the DontDelete cell without checking if it contains | 515 // from the DontDelete cell without checking if it contains |
516 // the hole value. | 516 // the hole value. |
517 Object* new_map; | 517 Map* new_map; |
518 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); | 518 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
519 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 519 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
520 } | 520 } |
521 set_map(Map::cast(new_map)); | 521 set_map(new_map); |
522 } | 522 } |
523 JSGlobalPropertyCell* cell = | 523 JSGlobalPropertyCell* cell = |
524 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); | 524 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); |
525 cell->set_value(cell->GetHeap()->the_hole_value()); | 525 cell->set_value(cell->GetHeap()->the_hole_value()); |
526 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 526 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
527 } else { | 527 } else { |
528 Object* deleted = dictionary->DeleteProperty(entry, mode); | 528 Object* deleted = dictionary->DeleteProperty(entry, mode); |
529 if (deleted == GetHeap()->true_value()) { | 529 if (deleted == GetHeap()->true_value()) { |
530 FixedArray* new_properties = NULL; | 530 FixedArray* new_properties = NULL; |
531 MaybeObject* maybe_properties = dictionary->Shrink(name); | 531 MaybeObject* maybe_properties = dictionary->Shrink(name); |
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1519 } | 1519 } |
1520 return true; | 1520 return true; |
1521 } | 1521 } |
1522 | 1522 |
1523 | 1523 |
1524 MaybeObject* JSObject::AddFastProperty(String* name, | 1524 MaybeObject* JSObject::AddFastProperty(String* name, |
1525 Object* value, | 1525 Object* value, |
1526 PropertyAttributes attributes, | 1526 PropertyAttributes attributes, |
1527 StoreFromKeyed store_mode) { | 1527 StoreFromKeyed store_mode) { |
1528 ASSERT(!IsJSGlobalProxy()); | 1528 ASSERT(!IsJSGlobalProxy()); |
1529 ASSERT(map()->instance_descriptors()->Search(name) == | |
1530 DescriptorArray::kNotFound); | |
1529 | 1531 |
1530 // Normalize the object if the name is an actual string (not the | 1532 // Normalize the object if the name is an actual string (not the |
1531 // hidden symbols) and is not a real identifier. | 1533 // hidden symbols) and is not a real identifier. |
1534 // Normalize the object if it will have too many fast properties. | |
1532 Isolate* isolate = GetHeap()->isolate(); | 1535 Isolate* isolate = GetHeap()->isolate(); |
1533 StringInputBuffer buffer(name); | 1536 StringInputBuffer buffer(name); |
1534 if (!IsIdentifier(isolate->unicode_cache(), &buffer) | 1537 if ((!IsIdentifier(isolate->unicode_cache(), &buffer) |
1535 && name != isolate->heap()->hidden_symbol()) { | 1538 && name != isolate->heap()->hidden_symbol()) || |
1539 (map()->unused_property_fields() == 0 && | |
1540 TooManyFastProperties(properties()->length(), store_mode))) { | |
1536 Object* obj; | 1541 Object* obj; |
1537 { MaybeObject* maybe_obj = | 1542 { MaybeObject* maybe_obj = |
1538 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1543 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
1539 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1544 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1540 } | 1545 } |
1541 return AddSlowProperty(name, value, attributes); | 1546 return AddSlowProperty(name, value, attributes); |
1542 } | 1547 } |
1543 | 1548 |
1544 DescriptorArray* old_descriptors = map()->instance_descriptors(); | 1549 DescriptorArray* old_descriptors = map()->instance_descriptors(); |
1545 // Compute the new index for new field. | 1550 // Compute the new index for new field. |
1546 int index = map()->NextFreePropertyIndex(); | 1551 int index = map()->NextFreePropertyIndex(); |
1547 | 1552 |
1548 // Allocate new instance descriptors with (name, index) added | 1553 // Allocate new instance descriptors with (name, index) added |
1549 FieldDescriptor new_field(name, index, attributes, 0); | 1554 FieldDescriptor new_field(name, index, attributes, 0); |
1550 DescriptorArray* new_descriptors; | 1555 DescriptorArray* new_descriptors; |
1551 { MaybeObject* maybe_new_descriptors = | 1556 { MaybeObject* maybe_new_descriptors = |
1552 old_descriptors->CopyInsert(&new_field); | 1557 old_descriptors->CopyInsert(&new_field); |
1553 if (!maybe_new_descriptors->To(&new_descriptors)) { | 1558 if (!maybe_new_descriptors->To(&new_descriptors)) { |
1554 return maybe_new_descriptors; | 1559 return maybe_new_descriptors; |
1555 } | 1560 } |
1556 } | 1561 } |
1557 | 1562 |
1558 // Only allow map transition if the object isn't the global object. | 1563 // Only allow map transition if the object isn't the global object. |
1559 bool allow_map_transition = | 1564 bool allow_map_transition = |
1560 (isolate->context()->global_context()->object_function()->map() != map()); | 1565 (isolate->context()->global_context()->object_function()->map() != map()); |
1561 | 1566 |
1562 ASSERT(old_descriptors->Search(name) == DescriptorArray::kNotFound); | |
1563 ASSERT(index < map()->inobject_properties() || | 1567 ASSERT(index < map()->inobject_properties() || |
1564 (index - map()->inobject_properties()) < properties()->length() || | 1568 (index - map()->inobject_properties()) < properties()->length() || |
1565 map()->unused_property_fields() == 0); | 1569 map()->unused_property_fields() == 0); |
1570 | |
danno
2012/07/11 14:17:52
nit: one space
| |
1571 | |
1566 // Allocate a new map for the object. | 1572 // Allocate a new map for the object. |
1567 Object* r; | 1573 Map* new_map; |
1568 { MaybeObject* maybe_r = map()->CopyDropDescriptors(); | 1574 { MaybeObject* maybe_r = map()->CopyReplaceDescriptors(new_descriptors); |
1569 if (!maybe_r->ToObject(&r)) return maybe_r; | 1575 if (!maybe_r->To(&new_map)) return maybe_r; |
1570 } | 1576 } |
1571 Map* new_map = Map::cast(r); | |
1572 | 1577 |
1573 TransitionArray* new_transitions = NULL; | 1578 TransitionArray* new_transitions = NULL; |
1574 if (allow_map_transition) { | 1579 if (allow_map_transition) { |
1575 MaybeObject* maybe_new_transitions = map()->AddTransition(name, new_map); | 1580 { MaybeObject* maybe_new_transitions = map()->AddTransition(name, new_map); |
danno
2012/07/11 14:17:52
Please remove
| |
1576 if (!maybe_new_transitions->To(&new_transitions)) { | 1581 if (!maybe_new_transitions->To(&new_transitions)) { |
1577 return maybe_new_transitions; | 1582 return maybe_new_transitions; |
1583 } | |
1578 } | 1584 } |
1579 } | 1585 } |
1580 | 1586 |
1581 if (map()->unused_property_fields() == 0) { | 1587 if (map()->unused_property_fields() == 0) { |
1582 if (TooManyFastProperties(properties()->length(), store_mode)) { | |
1583 Object* obj; | |
1584 { MaybeObject* maybe_obj = | |
1585 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | |
1586 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
1587 } | |
1588 return AddSlowProperty(name, value, attributes); | |
1589 } | |
1590 // Make room for the new value | 1588 // Make room for the new value |
1591 Object* values; | 1589 FixedArray* values; |
1592 { MaybeObject* maybe_values = | 1590 { MaybeObject* maybe_values = |
1593 properties()->CopySize(properties()->length() + kFieldsAdded); | 1591 properties()->CopySize(properties()->length() + kFieldsAdded); |
1594 if (!maybe_values->ToObject(&values)) return maybe_values; | 1592 if (!maybe_values->To(&values)) return maybe_values; |
1595 } | 1593 } |
1596 set_properties(FixedArray::cast(values)); | 1594 set_properties(values); |
1597 new_map->set_unused_property_fields(kFieldsAdded - 1); | 1595 new_map->set_unused_property_fields(kFieldsAdded - 1); |
1598 } else { | 1596 } else { |
1599 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); | 1597 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); |
1600 } | 1598 } |
1599 | |
1601 // Apply all changes at once, so they are atomic. | 1600 // Apply all changes at once, so they are atomic. |
1602 if (allow_map_transition) { | 1601 if (allow_map_transition) { |
1603 MaybeObject* transition_added = map()->set_transitions(new_transitions); | 1602 MaybeObject* transition_added = map()->set_transitions(new_transitions); |
1604 if (transition_added->IsFailure()) return transition_added; | 1603 if (transition_added->IsFailure()) return transition_added; |
1605 } | 1604 } |
1606 new_map->set_instance_descriptors(new_descriptors); | 1605 |
1607 new_map->SetBackPointer(map()); | 1606 new_map->SetBackPointer(map()); |
1608 set_map(new_map); | 1607 set_map(new_map); |
1609 return FastPropertyAtPut(index, value); | 1608 return FastPropertyAtPut(index, value); |
1610 } | 1609 } |
1611 | 1610 |
1612 | 1611 |
1613 MaybeObject* JSObject::AddConstantFunctionProperty( | 1612 MaybeObject* JSObject::AddConstantFunctionProperty( |
1614 String* name, | 1613 String* name, |
1615 JSFunction* function, | 1614 JSFunction* function, |
1616 PropertyAttributes attributes) { | 1615 PropertyAttributes attributes) { |
1617 // Allocate new instance descriptors with (name, function) added | 1616 // Allocate new instance descriptors with (name, function) added |
1618 ConstantFunctionDescriptor d(name, function, attributes, 0); | 1617 ConstantFunctionDescriptor d(name, function, attributes, 0); |
1619 DescriptorArray* new_descriptors; | 1618 DescriptorArray* new_descriptors; |
1620 { MaybeObject* maybe_new_descriptors = | 1619 { MaybeObject* maybe_new_descriptors = |
1621 map()->instance_descriptors()->CopyInsert(&d); | 1620 map()->instance_descriptors()->CopyInsert(&d); |
1622 if (!maybe_new_descriptors->To(&new_descriptors)) { | 1621 if (!maybe_new_descriptors->To(&new_descriptors)) { |
1623 return maybe_new_descriptors; | 1622 return maybe_new_descriptors; |
1624 } | 1623 } |
1625 } | 1624 } |
1626 | 1625 |
1627 // Allocate a new map for the object. | 1626 // Allocate a new map for the object. |
1628 Map* new_map; | 1627 Map* new_map; |
1629 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); | 1628 { MaybeObject* maybe_new_map = map()->CopyReplaceDescriptors(new_descriptors); |
1630 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 1629 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
1631 } | 1630 } |
1632 | 1631 |
1633 new_map->set_instance_descriptors(new_descriptors); | |
1634 Map* old_map = map(); | 1632 Map* old_map = map(); |
1635 set_map(new_map); | 1633 set_map(new_map); |
1636 | 1634 |
1637 // If the old map is the global object map (from new Object()), | 1635 // If the old map is the global object map (from new Object()), |
1638 // then transitions are not added to it, so we are done. | 1636 // then transitions are not added to it, so we are done. |
1639 Heap* heap = GetHeap(); | 1637 Heap* heap = GetHeap(); |
1640 if (old_map == heap->isolate()->context()->global_context()-> | 1638 if (old_map == heap->isolate()->context()->global_context()-> |
1641 object_function()->map()) { | 1639 object_function()->map()) { |
1642 return function; | 1640 return function; |
1643 } | 1641 } |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1853 { MaybeObject* maybe_obj = | 1851 { MaybeObject* maybe_obj = |
1854 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1852 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
1855 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1853 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1856 } | 1854 } |
1857 return ReplaceSlowProperty(name, new_value, attributes); | 1855 return ReplaceSlowProperty(name, new_value, attributes); |
1858 } | 1856 } |
1859 | 1857 |
1860 int index = map()->NextFreePropertyIndex(); | 1858 int index = map()->NextFreePropertyIndex(); |
1861 FieldDescriptor new_field(name, index, attributes, 0); | 1859 FieldDescriptor new_field(name, index, attributes, 0); |
1862 // Make a new DescriptorArray replacing an entry with FieldDescriptor. | 1860 // Make a new DescriptorArray replacing an entry with FieldDescriptor. |
1863 Object* descriptors_unchecked; | 1861 DescriptorArray* new_descriptors; |
1864 { MaybeObject* maybe_descriptors_unchecked = | 1862 { MaybeObject* maybe_descriptors = |
1865 map()->instance_descriptors()->CopyInsert(&new_field); | 1863 map()->instance_descriptors()->CopyInsert(&new_field); |
1866 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { | 1864 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
1867 return maybe_descriptors_unchecked; | |
1868 } | |
1869 } | 1865 } |
1870 DescriptorArray* new_descriptors = | |
1871 DescriptorArray::cast(descriptors_unchecked); | |
1872 | 1866 |
1873 // Make a new map for the object. | 1867 // Make a new map for the object. |
1874 Object* new_map_unchecked; | 1868 Map* new_map; |
1875 { MaybeObject* maybe_new_map_unchecked = map()->CopyDropDescriptors(); | 1869 { MaybeObject* maybe_new_map = map()->CopyReplaceDescriptors(new_descriptors); |
1876 if (!maybe_new_map_unchecked->ToObject(&new_map_unchecked)) { | 1870 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
1877 return maybe_new_map_unchecked; | |
1878 } | |
1879 } | 1871 } |
1880 Map* new_map = Map::cast(new_map_unchecked); | |
1881 new_map->set_instance_descriptors(new_descriptors); | |
1882 | 1872 |
1883 // Make new properties array if necessary. | 1873 // Make new properties array if necessary. |
1884 FixedArray* new_properties = 0; // Will always be NULL or a valid pointer. | 1874 FixedArray* new_properties = 0; // Will always be NULL or a valid pointer. |
1885 int new_unused_property_fields = map()->unused_property_fields() - 1; | 1875 int new_unused_property_fields = map()->unused_property_fields() - 1; |
1886 if (map()->unused_property_fields() == 0) { | 1876 if (map()->unused_property_fields() == 0) { |
1887 new_unused_property_fields = kFieldsAdded - 1; | 1877 new_unused_property_fields = kFieldsAdded - 1; |
1888 Object* new_properties_object; | 1878 Object* new_properties_object; |
1889 { MaybeObject* maybe_new_properties_object = | 1879 { MaybeObject* maybe_new_properties_object = |
1890 properties()->CopySize(properties()->length() + kFieldsAdded); | 1880 properties()->CopySize(properties()->length() + kFieldsAdded); |
1891 if (!maybe_new_properties_object->ToObject(&new_properties_object)) { | 1881 if (!maybe_new_properties_object->ToObject(&new_properties_object)) { |
(...skipping 2713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4605 Map* map1 = obj->map(); | 4595 Map* map1 = obj->map(); |
4606 CallbacksDescriptor callbacks_descr2(name, accessors2, attributes, 0); | 4596 CallbacksDescriptor callbacks_descr2(name, accessors2, attributes, 0); |
4607 DescriptorArray* descriptors2; | 4597 DescriptorArray* descriptors2; |
4608 { MaybeObject* maybe_descriptors2 = | 4598 { MaybeObject* maybe_descriptors2 = |
4609 map1->instance_descriptors()->CopyInsert(&callbacks_descr2); | 4599 map1->instance_descriptors()->CopyInsert(&callbacks_descr2); |
4610 if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2; | 4600 if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2; |
4611 } | 4601 } |
4612 | 4602 |
4613 // step 3: create a new map with the new descriptors | 4603 // step 3: create a new map with the new descriptors |
4614 Map* map2; | 4604 Map* map2; |
4615 { MaybeObject* maybe_map2 = map1->CopyDropDescriptors(); | 4605 { MaybeObject* maybe_map2 = map1->CopyReplaceDescriptors(descriptors2); |
4616 if (!maybe_map2->To(&map2)) return maybe_map2; | 4606 if (!maybe_map2->To(&map2)) return maybe_map2; |
4617 } | 4607 } |
4618 map2->set_instance_descriptors(descriptors2); | |
4619 | 4608 |
4620 // step 4: create a new getter/setter pair with a transition to the new map | 4609 // step 4: create a new getter/setter pair with a transition to the new map |
4621 AccessorPair* accessors1; | 4610 AccessorPair* accessors1; |
4622 { MaybeObject* maybe_accessors1 = heap->AllocateAccessorPair(); | 4611 { MaybeObject* maybe_accessors1 = heap->AllocateAccessorPair(); |
4623 if (!maybe_accessors1->To(&accessors1)) return maybe_accessors1; | 4612 if (!maybe_accessors1->To(&accessors1)) return maybe_accessors1; |
4624 } | 4613 } |
4625 accessors1->set(component, map2); | 4614 accessors1->set(component, map2); |
4626 | 4615 |
4627 // step 5: create a copy of the descriptors, incl. the new getter/setter pair | 4616 // step 5: create a copy of the descriptors, incl. the new getter/setter pair |
4628 // with the transition | 4617 // with the transition |
(...skipping 13 matching lines...) Expand all Loading... | |
4642 obj->set_map(map2); | 4631 obj->set_map(map2); |
4643 return obj; | 4632 return obj; |
4644 } | 4633 } |
4645 | 4634 |
4646 | 4635 |
4647 static bool TransitionToSameAccessor(Object* map, | 4636 static bool TransitionToSameAccessor(Object* map, |
4648 String* name, | 4637 String* name, |
4649 AccessorComponent component, | 4638 AccessorComponent component, |
4650 Object* accessor, | 4639 Object* accessor, |
4651 PropertyAttributes attributes ) { | 4640 PropertyAttributes attributes ) { |
4652 DescriptorArray* descs = Map::cast(map)->instance_descriptors(); | 4641 Map* transitioned_map = Map::cast(map); |
4642 DescriptorArray* descs = transitioned_map->instance_descriptors(); | |
4653 int number = descs->LastAdded(); | 4643 int number = descs->LastAdded(); |
4654 ASSERT(number != DescriptorArray::kNotFound); | |
4655 Object* target_accessor = | 4644 Object* target_accessor = |
4656 AccessorPair::cast(descs->GetCallbacksObject(number))->get(component); | 4645 AccessorPair::cast(descs->GetCallbacksObject(number))->get(component); |
4657 PropertyAttributes target_attributes = descs->GetDetails(number).attributes(); | 4646 PropertyAttributes target_attributes = descs->GetDetails(number).attributes(); |
4658 return target_accessor == accessor && target_attributes == attributes; | 4647 return target_accessor == accessor && target_attributes == attributes; |
4659 } | 4648 } |
4660 | 4649 |
4661 | 4650 |
4662 static MaybeObject* NewCallbackTransition(JSObject* obj, | 4651 static MaybeObject* NewCallbackTransition(JSObject* obj, |
4663 String* name, | 4652 String* name, |
4664 AccessorComponent component, | 4653 AccessorComponent component, |
(...skipping 11 matching lines...) Expand all Loading... | |
4676 Map* map2 = obj->map(); | 4665 Map* map2 = obj->map(); |
4677 CallbacksDescriptor callbacks_descr3(name, accessors3, attributes, 0); | 4666 CallbacksDescriptor callbacks_descr3(name, accessors3, attributes, 0); |
4678 DescriptorArray* descriptors3; | 4667 DescriptorArray* descriptors3; |
4679 { MaybeObject* maybe_descriptors3 = | 4668 { MaybeObject* maybe_descriptors3 = |
4680 map2->instance_descriptors()->CopyInsert(&callbacks_descr3); | 4669 map2->instance_descriptors()->CopyInsert(&callbacks_descr3); |
4681 if (!maybe_descriptors3->To(&descriptors3)) return maybe_descriptors3; | 4670 if (!maybe_descriptors3->To(&descriptors3)) return maybe_descriptors3; |
4682 } | 4671 } |
4683 | 4672 |
4684 // step 3: create a new map with the new descriptors | 4673 // step 3: create a new map with the new descriptors |
4685 Map* map3; | 4674 Map* map3; |
4686 { MaybeObject* maybe_map3 = map2->CopyDropDescriptors(); | 4675 { MaybeObject* maybe_map3 = map2->CopyReplaceDescriptors(descriptors3); |
4687 if (!maybe_map3->To(&map3)) return maybe_map3; | 4676 if (!maybe_map3->To(&map3)) return maybe_map3; |
4688 } | 4677 } |
4689 map3->set_instance_descriptors(descriptors3); | |
4690 | 4678 |
4691 // step 4: add a new transition to the new map | 4679 // step 4: add a new transition to the new map |
4692 TransitionArray* new_transitions; | 4680 TransitionArray* new_transitions; |
4693 { MaybeObject* maybe_transitions = map2->AddTransition(name, accessors2); | 4681 { MaybeObject* maybe_transitions = map2->AddTransition(name, accessors2); |
4694 if (!maybe_transitions->To(&new_transitions)) return maybe_transitions; | 4682 if (!maybe_transitions->To(&new_transitions)) return maybe_transitions; |
4695 } | 4683 } |
4696 | 4684 |
4697 // step 5: everything went well so far, so we make our changes visible | 4685 // step 5: everything went well so far, so we make our changes visible |
4698 { MaybeObject* transition_added = map2->set_transitions(new_transitions); | 4686 { MaybeObject* transition_added = map2->set_transitions(new_transitions); |
4699 if (transition_added->IsFailure()) return transition_added; | 4687 if (transition_added->IsFailure()) return transition_added; |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4902 } | 4890 } |
4903 } | 4891 } |
4904 } | 4892 } |
4905 return GetHeap()->undefined_value(); | 4893 return GetHeap()->undefined_value(); |
4906 } else { | 4894 } else { |
4907 return property_dictionary()->SlowReverseLookup(value); | 4895 return property_dictionary()->SlowReverseLookup(value); |
4908 } | 4896 } |
4909 } | 4897 } |
4910 | 4898 |
4911 | 4899 |
4912 MaybeObject* Map::CopyDropDescriptors() { | 4900 MaybeObject* Map::RawCopy(int instance_size) { |
4913 Heap* heap = GetHeap(); | 4901 Map* result; |
4914 Object* result; | |
4915 { MaybeObject* maybe_result = | 4902 { MaybeObject* maybe_result = |
4916 heap->AllocateMap(instance_type(), instance_size()); | 4903 GetHeap()->AllocateMap(instance_type(), instance_size); |
4917 if (!maybe_result->ToObject(&result)) return maybe_result; | 4904 if (!maybe_result->To(&result)) return maybe_result; |
4918 } | 4905 } |
4919 Map::cast(result)->set_prototype(prototype()); | |
4920 Map::cast(result)->set_constructor(constructor()); | |
4921 | 4906 |
4922 // Please note instance_type and instance_size are set when allocated. | 4907 result->set_prototype(prototype()); |
4923 Map::cast(result)->set_inobject_properties(inobject_properties()); | 4908 result->set_constructor(constructor()); |
4924 Map::cast(result)->set_unused_property_fields(unused_property_fields()); | 4909 result->set_bit_field(bit_field()); |
4925 | 4910 result->set_bit_field2(bit_field2()); |
4926 // If the map has pre-allocated properties always start out with a descriptor | 4911 result->set_bit_field3(bit_field3()); |
4927 // array describing these properties. | |
4928 if (pre_allocated_property_fields() > 0) { | |
4929 ASSERT(constructor()->IsJSFunction()); | |
4930 JSFunction* ctor = JSFunction::cast(constructor()); | |
4931 Object* descriptors; | |
4932 { MaybeObject* maybe_descriptors = | |
4933 ctor->initial_map()->instance_descriptors()->Copy( | |
4934 DescriptorArray::MAY_BE_SHARED); | |
4935 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors; | |
4936 } | |
4937 Map::cast(result)->set_instance_descriptors( | |
4938 DescriptorArray::cast(descriptors)); | |
4939 Map::cast(result)->set_pre_allocated_property_fields( | |
4940 pre_allocated_property_fields()); | |
4941 } | |
4942 Map::cast(result)->set_bit_field(bit_field()); | |
4943 Map::cast(result)->set_bit_field2(bit_field2()); | |
4944 Map::cast(result)->set_bit_field3(bit_field3()); | |
4945 Map::cast(result)->set_is_shared(false); | |
4946 Map::cast(result)->ClearCodeCache(heap); | |
4947 return result; | 4912 return result; |
4948 } | 4913 } |
4949 | 4914 |
4950 | 4915 |
4951 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, | 4916 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, |
4952 NormalizedMapSharingMode sharing) { | 4917 NormalizedMapSharingMode sharing) { |
4953 int new_instance_size = instance_size(); | 4918 int new_instance_size = instance_size(); |
4954 if (mode == CLEAR_INOBJECT_PROPERTIES) { | 4919 if (mode == CLEAR_INOBJECT_PROPERTIES) { |
4955 new_instance_size -= inobject_properties() * kPointerSize; | 4920 new_instance_size -= inobject_properties() * kPointerSize; |
4956 } | 4921 } |
4957 | 4922 |
4958 Object* result; | 4923 Map* result; |
4959 { MaybeObject* maybe_result = | 4924 { MaybeObject* maybe_result = RawCopy(new_instance_size); |
4960 GetHeap()->AllocateMap(instance_type(), new_instance_size); | 4925 if (!maybe_result->To(&result)) return maybe_result; |
4961 if (!maybe_result->ToObject(&result)) return maybe_result; | |
4962 } | 4926 } |
4963 | 4927 |
4964 if (mode != CLEAR_INOBJECT_PROPERTIES) { | 4928 if (mode != CLEAR_INOBJECT_PROPERTIES) { |
4965 Map::cast(result)->set_inobject_properties(inobject_properties()); | 4929 result->set_inobject_properties(inobject_properties()); |
4966 } | 4930 } |
4967 | 4931 |
4968 Map::cast(result)->set_prototype(prototype()); | 4932 result->set_code_cache(code_cache()); |
4969 Map::cast(result)->set_constructor(constructor()); | 4933 result->set_is_shared(sharing == SHARED_NORMALIZED_MAP); |
4970 | |
4971 Map::cast(result)->set_bit_field(bit_field()); | |
4972 Map::cast(result)->set_bit_field2(bit_field2()); | |
4973 Map::cast(result)->set_bit_field3(bit_field3()); | |
4974 Map::cast(result)->set_code_cache(code_cache()); | |
4975 | |
4976 Map::cast(result)->set_is_shared(sharing == SHARED_NORMALIZED_MAP); | |
4977 | 4934 |
4978 #ifdef DEBUG | 4935 #ifdef DEBUG |
4979 if (FLAG_verify_heap && Map::cast(result)->is_shared()) { | 4936 if (FLAG_verify_heap && Map::cast(result)->is_shared()) { |
4980 Map::cast(result)->SharedMapVerify(); | 4937 result->SharedMapVerify(); |
4981 } | 4938 } |
4982 #endif | 4939 #endif |
4983 | 4940 |
4984 return result; | 4941 return result; |
4985 } | 4942 } |
4986 | 4943 |
4987 | 4944 |
4988 MaybeObject* Map::CopyDropTransitions( | 4945 MaybeObject* Map::CopyDropDescriptors() { |
4989 DescriptorArray::SharedMode shared_mode) { | 4946 Map* result; |
4990 Object* new_map; | 4947 { MaybeObject* maybe_result = RawCopy(instance_size()); |
4991 { MaybeObject* maybe_new_map = CopyDropDescriptors(); | 4948 if (!maybe_result->To(&result)) return maybe_result; |
4992 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | |
4993 } | 4949 } |
4994 Object* descriptors; | 4950 |
4995 { MaybeObject* maybe_descriptors = | 4951 // Please note instance_type and instance_size are set when allocated. |
4996 instance_descriptors()->Copy(shared_mode); | 4952 result->set_inobject_properties(inobject_properties()); |
4997 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors; | 4953 result->set_unused_property_fields(unused_property_fields()); |
4998 } | 4954 |
4999 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); | 4955 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); |
5000 return new_map; | 4956 result->set_is_shared(false); |
4957 result->ClearCodeCache(GetHeap()); | |
4958 return result; | |
5001 } | 4959 } |
5002 | 4960 |
5003 | 4961 |
4962 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors) { | |
4963 Map* result; | |
4964 { MaybeObject* maybe_result = CopyDropDescriptors(); | |
4965 if (!maybe_result->To(&result)) return maybe_result; | |
4966 } | |
4967 result->set_instance_descriptors(descriptors); | |
4968 return result; | |
4969 } | |
4970 | |
4971 | |
4972 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() { | |
4973 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors(); | |
4974 | |
4975 // If the map has pre-allocated properties always start out with a descriptor | |
4976 // array describing these properties. | |
4977 ASSERT(constructor()->IsJSFunction()); | |
4978 JSFunction* ctor = JSFunction::cast(constructor()); | |
4979 DescriptorArray* descriptors; | |
4980 { MaybeObject* maybe_descriptors = | |
4981 ctor->initial_map()->instance_descriptors()->Copy( | |
4982 DescriptorArray::MAY_BE_SHARED); | |
4983 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | |
4984 } | |
4985 return CopyReplaceDescriptors(descriptors); | |
4986 } | |
4987 | |
4988 | |
4989 MaybeObject* Map::CopyDropTransitions(DescriptorArray::SharedMode shared_mode) { | |
4990 DescriptorArray* descriptors; | |
4991 { MaybeObject* maybe_descriptors = instance_descriptors()->Copy(shared_mode); | |
4992 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | |
4993 } | |
4994 return CopyReplaceDescriptors(descriptors); | |
4995 } | |
4996 | |
4997 | |
5004 void Map::UpdateCodeCache(Handle<Map> map, | 4998 void Map::UpdateCodeCache(Handle<Map> map, |
5005 Handle<String> name, | 4999 Handle<String> name, |
5006 Handle<Code> code) { | 5000 Handle<Code> code) { |
5007 Isolate* isolate = map->GetIsolate(); | 5001 Isolate* isolate = map->GetIsolate(); |
5008 CALL_HEAP_FUNCTION_VOID(isolate, | 5002 CALL_HEAP_FUNCTION_VOID(isolate, |
5009 map->UpdateCodeCache(*name, *code)); | 5003 map->UpdateCodeCache(*name, *code)); |
5010 } | 5004 } |
5011 | 5005 |
5012 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { | 5006 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { |
5013 ASSERT(!is_shared() || code->allowed_in_shared_map_code_cache()); | 5007 ASSERT(!is_shared() || code->allowed_in_shared_map_code_cache()); |
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5921 MaybeObject* copy_result = | 5915 MaybeObject* copy_result = |
5922 new_descriptors->CopyFrom(to_index++, this, from_index, witness); | 5916 new_descriptors->CopyFrom(to_index++, this, from_index, witness); |
5923 if (copy_result->IsFailure()) return copy_result; | 5917 if (copy_result->IsFailure()) return copy_result; |
5924 from_index++; | 5918 from_index++; |
5925 } | 5919 } |
5926 } | 5920 } |
5927 if (insertion_index < 0) insertion_index = to_index++; | 5921 if (insertion_index < 0) insertion_index = to_index++; |
5928 | 5922 |
5929 ASSERT(insertion_index < new_descriptors->number_of_descriptors()); | 5923 ASSERT(insertion_index < new_descriptors->number_of_descriptors()); |
5930 new_descriptors->Set(insertion_index, descriptor, witness); | 5924 new_descriptors->Set(insertion_index, descriptor, witness); |
5925 | |
5931 if (!replacing) { | 5926 if (!replacing) { |
5932 new_descriptors->SetLastAdded(insertion_index); | 5927 new_descriptors->SetLastAdded(insertion_index); |
5933 } else { | 5928 } else { |
5934 new_descriptors->SetLastAdded(LastAdded()); | 5929 new_descriptors->SetLastAdded(LastAdded()); |
5935 } | 5930 } |
5936 | 5931 |
5937 ASSERT(to_index == new_descriptors->number_of_descriptors()); | 5932 ASSERT(to_index == new_descriptors->number_of_descriptors()); |
5938 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); | 5933 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); |
5939 | 5934 |
5940 return new_descriptors; | 5935 return new_descriptors; |
(...skipping 6817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12758 } else { | 12753 } else { |
12759 UNREACHABLE(); | 12754 UNREACHABLE(); |
12760 } | 12755 } |
12761 ++next_descriptor; | 12756 ++next_descriptor; |
12762 } | 12757 } |
12763 } | 12758 } |
12764 ASSERT(current_offset == number_of_fields); | 12759 ASSERT(current_offset == number_of_fields); |
12765 | 12760 |
12766 descriptors->Sort(witness); | 12761 descriptors->Sort(witness); |
12767 // Allocate new map. | 12762 // Allocate new map. |
12768 Object* new_map; | 12763 Map* new_map; |
12769 { MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors(); | 12764 { MaybeObject* maybe_new_map = |
12770 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 12765 obj->map()->CopyReplaceDescriptors(descriptors); |
12766 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
12771 } | 12767 } |
12772 | 12768 |
12769 new_map->set_unused_property_fields(unused_property_fields); | |
12770 | |
12773 // Transform the object. | 12771 // Transform the object. |
12774 obj->set_map(Map::cast(new_map)); | 12772 obj->set_map(new_map); |
12775 obj->map()->set_instance_descriptors(descriptors); | |
12776 obj->map()->set_unused_property_fields(unused_property_fields); | |
12777 | 12773 |
12778 obj->set_properties(FixedArray::cast(fields)); | 12774 obj->set_properties(FixedArray::cast(fields)); |
12779 ASSERT(obj->IsJSObject()); | 12775 ASSERT(obj->IsJSObject()); |
12780 | 12776 |
12781 // Check that it really works. | 12777 // Check that it really works. |
12782 ASSERT(obj->HasFastProperties()); | 12778 ASSERT(obj->HasFastProperties()); |
12783 | 12779 |
12784 return obj; | 12780 return obj; |
12785 } | 12781 } |
12786 | 12782 |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13282 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13278 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
13283 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13279 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
13284 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13280 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
13285 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13281 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
13286 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13282 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
13287 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13283 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
13288 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13284 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
13289 } | 13285 } |
13290 | 13286 |
13291 } } // namespace v8::internal | 13287 } } // namespace v8::internal |
OLD | NEW |