Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: src/objects.cc

Issue 10700160: Refactor copying of maps and descriptor arrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698