| Index: src/heap.cc | 
| diff --git a/src/heap.cc b/src/heap.cc | 
| index 2817fcba58264f29d0d6d087cca965507d3b7662..de15e5e593d332d8e5c69d449f50125505dcd67c 100644 | 
| --- a/src/heap.cc | 
| +++ b/src/heap.cc | 
| @@ -105,6 +105,7 @@ Heap::Heap() | 
| code_space_(NULL), | 
| map_space_(NULL), | 
| cell_space_(NULL), | 
| +      property_cell_space_(NULL), | 
| lo_space_(NULL), | 
| gc_state_(NOT_IN_GC), | 
| gc_post_processing_depth_(0), | 
| @@ -199,7 +200,8 @@ intptr_t Heap::Capacity() { | 
| old_data_space_->Capacity() + | 
| code_space_->Capacity() + | 
| map_space_->Capacity() + | 
| -      cell_space_->Capacity(); | 
| +      cell_space_->Capacity() + | 
| +      property_cell_space_->Capacity(); | 
| } | 
|  | 
|  | 
| @@ -212,6 +214,7 @@ intptr_t Heap::CommittedMemory() { | 
| code_space_->CommittedMemory() + | 
| map_space_->CommittedMemory() + | 
| cell_space_->CommittedMemory() + | 
| +      property_cell_space_->CommittedMemory() + | 
| lo_space_->Size(); | 
| } | 
|  | 
| @@ -225,6 +228,7 @@ size_t Heap::CommittedPhysicalMemory() { | 
| code_space_->CommittedPhysicalMemory() + | 
| map_space_->CommittedPhysicalMemory() + | 
| cell_space_->CommittedPhysicalMemory() + | 
| +      property_cell_space_->CommittedPhysicalMemory() + | 
| lo_space_->CommittedPhysicalMemory(); | 
| } | 
|  | 
| @@ -244,7 +248,8 @@ intptr_t Heap::Available() { | 
| old_data_space_->Available() + | 
| code_space_->Available() + | 
| map_space_->Available() + | 
| -      cell_space_->Available(); | 
| +      cell_space_->Available() + | 
| +      property_cell_space_->Available(); | 
| } | 
|  | 
|  | 
| @@ -254,6 +259,7 @@ bool Heap::HasBeenSetUp() { | 
| code_space_ != NULL && | 
| map_space_ != NULL && | 
| cell_space_ != NULL && | 
| +         property_cell_space_ != NULL && | 
| lo_space_ != NULL; | 
| } | 
|  | 
| @@ -383,6 +389,12 @@ void Heap::PrintShortHeapStatistics() { | 
| cell_space_->SizeOfObjects() / KB, | 
| cell_space_->Available() / KB, | 
| cell_space_->CommittedMemory() / KB); | 
| +  PrintPID("PropertyCell space, used: %6" V8_PTR_PREFIX "d KB" | 
| +               ", available: %6" V8_PTR_PREFIX "d KB" | 
| +               ", committed: %6" V8_PTR_PREFIX "d KB\n", | 
| +           property_cell_space_->SizeOfObjects() / KB, | 
| +           property_cell_space_->Available() / KB, | 
| +           property_cell_space_->CommittedMemory() / KB); | 
| PrintPID("Large object space, used: %6" V8_PTR_PREFIX "d KB" | 
| ", available: %6" V8_PTR_PREFIX "d KB" | 
| ", committed: %6" V8_PTR_PREFIX "d KB\n", | 
| @@ -514,6 +526,10 @@ void Heap::GarbageCollectionEpilogue() { | 
| isolate_->counters()->heap_fraction_cell_space()->AddSample( | 
| static_cast<int>( | 
| (cell_space()->CommittedMemory() * 100.0) / CommittedMemory())); | 
| +    isolate_->counters()->heap_fraction_property_cell_space()-> | 
| +        AddSample(static_cast<int>( | 
| +            (property_cell_space()->CommittedMemory() * 100.0) / | 
| +            CommittedMemory())); | 
|  | 
| isolate_->counters()->heap_sample_total_committed()->AddSample( | 
| static_cast<int>(CommittedMemory() / KB)); | 
| @@ -523,6 +539,10 @@ void Heap::GarbageCollectionEpilogue() { | 
| static_cast<int>(map_space()->CommittedMemory() / KB)); | 
| isolate_->counters()->heap_sample_cell_space_committed()->AddSample( | 
| static_cast<int>(cell_space()->CommittedMemory() / KB)); | 
| +    isolate_->counters()-> | 
| +        heap_sample_property_cell_space_committed()-> | 
| +            AddSample(static_cast<int>( | 
| +                property_cell_space()->CommittedMemory() / KB)); | 
| } | 
|  | 
| #define UPDATE_COUNTERS_FOR_SPACE(space)                                       \ | 
| @@ -548,6 +568,7 @@ void Heap::GarbageCollectionEpilogue() { | 
| UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(code_space) | 
| UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(map_space) | 
| UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(cell_space) | 
| +  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(property_cell_space) | 
| UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(lo_space) | 
| #undef UPDATE_COUNTERS_FOR_SPACE | 
| #undef UPDATE_FRAGMENTATION_FOR_SPACE | 
| @@ -1353,15 +1374,31 @@ void Heap::Scavenge() { | 
| store_buffer()->IteratePointersToNewSpace(&ScavengeObject); | 
| } | 
|  | 
| -  // Copy objects reachable from cells by scavenging cell values directly. | 
| +  // Copy objects reachable from simple cells by scavenging cell values | 
| +  // directly. | 
| HeapObjectIterator cell_iterator(cell_space_); | 
| for (HeapObject* heap_object = cell_iterator.Next(); | 
| heap_object != NULL; | 
| heap_object = cell_iterator.Next()) { | 
| +    if (heap_object->IsCell()) { | 
| +      Cell* cell = Cell::cast(heap_object); | 
| +      Address value_address = cell->ValueAddress(); | 
| +      scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); | 
| +    } | 
| +  } | 
| + | 
| +  // Copy objects reachable from global property cells by scavenging global | 
| +  // property cell values directly. | 
| +  HeapObjectIterator js_global_property_cell_iterator(property_cell_space_); | 
| +  for (HeapObject* heap_object = js_global_property_cell_iterator.Next(); | 
| +       heap_object != NULL; | 
| +       heap_object = js_global_property_cell_iterator.Next()) { | 
| if (heap_object->IsJSGlobalPropertyCell()) { | 
| JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(heap_object); | 
| Address value_address = cell->ValueAddress(); | 
| scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); | 
| +      Address type_address = cell->TypeAddress(); | 
| +      scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(type_address)); | 
| } | 
| } | 
|  | 
| @@ -2663,7 +2700,12 @@ bool Heap::CreateInitialMaps() { | 
| } | 
| set_code_map(Map::cast(obj)); | 
|  | 
| -  { MaybeObject* maybe_obj = AllocateMap(JS_GLOBAL_PROPERTY_CELL_TYPE, | 
| +  { MaybeObject* maybe_obj = AllocateMap(CELL_TYPE, Cell::kSize); | 
| +    if (!maybe_obj->ToObject(&obj)) return false; | 
| +  } | 
| +  set_cell_map(Map::cast(obj)); | 
| + | 
| +  { MaybeObject* maybe_obj = AllocateMap(PROPERTY_CELL_TYPE, | 
| JSGlobalPropertyCell::kSize); | 
| if (!maybe_obj->ToObject(&obj)) return false; | 
| } | 
| @@ -2798,14 +2840,26 @@ MaybeObject* Heap::AllocateHeapNumber(double value) { | 
| } | 
|  | 
|  | 
| -MaybeObject* Heap::AllocateJSGlobalPropertyCell(Object* value) { | 
| +MaybeObject* Heap::AllocateCell(Object* value) { | 
| Object* result; | 
| { MaybeObject* maybe_result = AllocateRawCell(); | 
| if (!maybe_result->ToObject(&result)) return maybe_result; | 
| } | 
| +  HeapObject::cast(result)->set_map_no_write_barrier(cell_map()); | 
| +  Cell::cast(result)->set_value(value); | 
| +  return result; | 
| +} | 
| + | 
| + | 
| +MaybeObject* Heap::AllocateJSGlobalPropertyCell(Object* value) { | 
| +  Object* result; | 
| +  { MaybeObject* maybe_result = AllocateRawJSGlobalPropertyCell(); | 
| +    if (!maybe_result->ToObject(&result)) return maybe_result; | 
| +  } | 
| HeapObject::cast(result)->set_map_no_write_barrier( | 
| global_property_cell_map()); | 
| JSGlobalPropertyCell::cast(result)->set_value(value); | 
| +  JSGlobalPropertyCell::cast(result)->set_type(Type::None()); | 
| return result; | 
| } | 
|  | 
| @@ -4469,8 +4523,7 @@ MaybeObject* Heap::AllocateJSObjectWithAllocationSite(JSFunction* constructor, | 
| // advice | 
| Map* initial_map = constructor->initial_map(); | 
|  | 
| -  JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast( | 
| -      *allocation_site_info_payload); | 
| +  Cell* cell = Cell::cast(*allocation_site_info_payload); | 
| Smi* smi = Smi::cast(cell->value()); | 
| ElementsKind to_kind = static_cast<ElementsKind>(smi->value()); | 
| AllocationSiteMode mode = TRACK_ALLOCATION_SITE; | 
| @@ -6052,6 +6105,8 @@ void Heap::ReportHeapStatistics(const char* title) { | 
| map_space_->ReportStatistics(); | 
| PrintF("Cell space : "); | 
| cell_space_->ReportStatistics(); | 
| +  PrintF("JSGlobalPropertyCell space : "); | 
| +  property_cell_space_->ReportStatistics(); | 
| PrintF("Large object space : "); | 
| lo_space_->ReportStatistics(); | 
| PrintF(">>>>>> ========================================= >>>>>>\n"); | 
| @@ -6073,6 +6128,7 @@ bool Heap::Contains(Address addr) { | 
| code_space_->Contains(addr) || | 
| map_space_->Contains(addr) || | 
| cell_space_->Contains(addr) || | 
| +     property_cell_space_->Contains(addr) || | 
| lo_space_->SlowContains(addr)); | 
| } | 
|  | 
| @@ -6099,6 +6155,8 @@ bool Heap::InSpace(Address addr, AllocationSpace space) { | 
| return map_space_->Contains(addr); | 
| case CELL_SPACE: | 
| return cell_space_->Contains(addr); | 
| +    case PROPERTY_CELL_SPACE: | 
| +      return property_cell_space_->Contains(addr); | 
| case LO_SPACE: | 
| return lo_space_->SlowContains(addr); | 
| } | 
| @@ -6125,6 +6183,7 @@ void Heap::Verify() { | 
| old_data_space_->Verify(&no_dirty_regions_visitor); | 
| code_space_->Verify(&no_dirty_regions_visitor); | 
| cell_space_->Verify(&no_dirty_regions_visitor); | 
| +  property_cell_space_->Verify(&no_dirty_regions_visitor); | 
|  | 
| lo_space_->Verify(); | 
| } | 
| @@ -6624,6 +6683,8 @@ void Heap::RecordStats(HeapStats* stats, bool take_snapshot) { | 
| *stats->map_space_capacity = map_space_->Capacity(); | 
| *stats->cell_space_size = cell_space_->SizeOfObjects(); | 
| *stats->cell_space_capacity = cell_space_->Capacity(); | 
| +  *stats->property_cell_space_size = property_cell_space_->SizeOfObjects(); | 
| +  *stats->property_cell_space_capacity = property_cell_space_->Capacity(); | 
| *stats->lo_space_size = lo_space_->Size(); | 
| isolate_->global_handles()->RecordStats(stats); | 
| *stats->memory_allocator_size = isolate()->memory_allocator()->Size(); | 
| @@ -6652,6 +6713,7 @@ intptr_t Heap::PromotedSpaceSizeOfObjects() { | 
| + code_space_->SizeOfObjects() | 
| + map_space_->SizeOfObjects() | 
| + cell_space_->SizeOfObjects() | 
| +      + property_cell_space_->SizeOfObjects() | 
| + lo_space_->SizeOfObjects(); | 
| } | 
|  | 
| @@ -6740,11 +6802,17 @@ bool Heap::SetUp() { | 
| if (map_space_ == NULL) return false; | 
| if (!map_space_->SetUp()) return false; | 
|  | 
| -  // Initialize global property cell space. | 
| +  // Initialize simple cell space. | 
| cell_space_ = new CellSpace(this, max_old_generation_size_, CELL_SPACE); | 
| if (cell_space_ == NULL) return false; | 
| if (!cell_space_->SetUp()) return false; | 
|  | 
| +  // Initialize global property cell space. | 
| +  property_cell_space_ = new PropertyCellSpace(this, max_old_generation_size_, | 
| +                                               PROPERTY_CELL_SPACE); | 
| +  if (property_cell_space_ == NULL) return false; | 
| +  if (!property_cell_space_->SetUp()) return false; | 
| + | 
| // The large object code space may contain code or data.  We set the memory | 
| // to be non-executable here for safety, but this means we need to enable it | 
| // explicitly when allocating large code objects. | 
| @@ -6865,6 +6933,12 @@ void Heap::TearDown() { | 
| cell_space_ = NULL; | 
| } | 
|  | 
| +  if (property_cell_space_ != NULL) { | 
| +    property_cell_space_->TearDown(); | 
| +    delete property_cell_space_; | 
| +    property_cell_space_ = NULL; | 
| +  } | 
| + | 
| if (lo_space_ != NULL) { | 
| lo_space_->TearDown(); | 
| delete lo_space_; | 
| @@ -6955,6 +7029,8 @@ Space* AllSpaces::next() { | 
| return heap_->map_space(); | 
| case CELL_SPACE: | 
| return heap_->cell_space(); | 
| +    case PROPERTY_CELL_SPACE: | 
| +      return heap_->property_cell_space(); | 
| case LO_SPACE: | 
| return heap_->lo_space(); | 
| default: | 
| @@ -6975,6 +7051,8 @@ PagedSpace* PagedSpaces::next() { | 
| return heap_->map_space(); | 
| case CELL_SPACE: | 
| return heap_->cell_space(); | 
| +    case PROPERTY_CELL_SPACE: | 
| +      return heap_->property_cell_space(); | 
| default: | 
| return NULL; | 
| } | 
| @@ -7064,6 +7142,10 @@ ObjectIterator* SpaceIterator::CreateIterator() { | 
| case CELL_SPACE: | 
| iterator_ = new HeapObjectIterator(heap_->cell_space(), size_func_); | 
| break; | 
| +    case PROPERTY_CELL_SPACE: | 
| +      iterator_ = new HeapObjectIterator(heap_->property_cell_space(), | 
| +                                         size_func_); | 
| +      break; | 
| case LO_SPACE: | 
| iterator_ = new LargeObjectIterator(heap_->lo_space(), size_func_); | 
| break; | 
|  |