Commit ea115267 authored by jochen's avatar jochen Committed by Commit bot

Make JSProxies always be in slow mode

That way, we don't have to implement the fast <-> slow migration logic,
and we don't allocate in-object properties anyways

BUG=chromium:571365
R=verwaest@chromium.org,neis@chromium.org
LOG=n

Review URL: https://codereview.chromium.org/1582773003

Cr-Commit-Position: refs/heads/master@{#33328}
parent a6900e0c
......@@ -2458,6 +2458,7 @@ void Genesis::InstallJSProxyMaps() {
Handle<Map> proxy_map =
factory()->NewMap(JS_PROXY_TYPE, JSProxy::kSize, FAST_ELEMENTS);
proxy_map->set_dictionary_map(true);
native_context()->set_proxy_map(*proxy_map);
Handle<Map> proxy_callable_map = Map::Copy(proxy_map, "callable Proxy");
......
......@@ -2752,6 +2752,11 @@ void Heap::CreateInitialObjects() {
Runtime::InitializeIntrinsicFunctionNames(isolate(), intrinsic_names);
set_intrinsic_function_names(*intrinsic_names);
Handle<NameDictionary> empty_properties_dictionary =
NameDictionary::New(isolate(), 0, TENURED);
empty_properties_dictionary->SetRequiresCopyOnCapacityChange();
set_empty_properties_dictionary(*empty_properties_dictionary);
set_number_string_cache(
*factory->NewFixedArray(kInitialNumberStringCacheSize * 2, TENURED));
......
......@@ -169,6 +169,7 @@ namespace internal {
ExperimentalExtraNativesSourceCache) \
V(Script, empty_script, EmptyScript) \
V(NameDictionary, intrinsic_function_names, IntrinsicFunctionNames) \
V(NameDictionary, empty_properties_dictionary, EmptyPropertiesDictionary) \
V(Cell, undefined_cell, UndefinedCell) \
V(JSObject, observation_state, ObservationState) \
V(Object, symbol_registry, SymbolRegistry) \
......
......@@ -7067,7 +7067,13 @@ MaybeHandle<Object> Object::GetPropertyOrElement(Handle<JSReceiver> holder,
void JSReceiver::initialize_properties() {
DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_properties_dictionary()));
if (map()->is_dictionary_map()) {
WRITE_FIELD(this, kPropertiesOffset,
GetHeap()->empty_properties_dictionary());
} else {
WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
}
}
......
......@@ -17184,14 +17184,8 @@ Handle<Derived> HashTable<Derived, Shape, Key>::EnsureCapacity(
Isolate* isolate = table->GetIsolate();
int capacity = table->Capacity();
int nof = table->NumberOfElements() + n;
int nod = table->NumberOfDeletedElements();
// Return if:
// 50% is still free after adding n elements and
// at most 50% of the free elements are deleted elements.
if (nod <= (capacity - nof) >> 1) {
int needed_free = nof >> 1;
if (nof + needed_free <= capacity) return table;
}
if (table->HasSufficientCapacity(n)) return table;
const int kMinCapacityForPretenure = 256;
bool should_pretenure = pretenure == TENURED ||
......@@ -17208,6 +17202,22 @@ Handle<Derived> HashTable<Derived, Shape, Key>::EnsureCapacity(
}
template <typename Derived, typename Shape, typename Key>
bool HashTable<Derived, Shape, Key>::HasSufficientCapacity(int n) {
int capacity = Capacity();
int nof = NumberOfElements() + n;
int nod = NumberOfDeletedElements();
// Return true if:
// 50% is still free after adding n elements and
// at most 50% of the free elements are deleted elements.
if (nod <= (capacity - nof) >> 1) {
int needed_free = nof >> 1;
if (nof + needed_free <= capacity) return true;
}
return false;
}
template<typename Derived, typename Shape, typename Key>
Handle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table,
Key key) {
......@@ -17374,6 +17384,9 @@ template Handle<UnseededNumberDictionary>
Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
EnsureCapacity(Handle<UnseededNumberDictionary>, int, uint32_t);
template void Dictionary<NameDictionary, NameDictionaryShape,
Handle<Name> >::SetRequiresCopyOnCapacityChange();
template Handle<NameDictionary>
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
EnsureCapacity(Handle<NameDictionary>, int, Handle<Name>);
......@@ -18102,7 +18115,17 @@ Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices(
}
template<typename Derived, typename Shape, typename Key>
template <typename Derived, typename Shape, typename Key>
void Dictionary<Derived, Shape, Key>::SetRequiresCopyOnCapacityChange() {
DCHECK_EQ(0, DerivedHashTable::NumberOfElements());
DCHECK_EQ(0, DerivedHashTable::NumberOfDeletedElements());
// Make sure that HashTable::EnsureCapacity will create a copy.
DerivedHashTable::SetNumberOfDeletedElements(DerivedHashTable::Capacity());
DCHECK(!DerivedHashTable::HasSufficientCapacity(1));
}
template <typename Derived, typename Shape, typename Key>
Handle<Derived> Dictionary<Derived, Shape, Key>::EnsureCapacity(
Handle<Derived> dictionary, int n, Key key) {
// Check whether there are enough enumeration indices to add n elements.
......
......@@ -3221,6 +3221,9 @@ class HashTable : public HashTableBase {
Key key,
PretenureFlag pretenure = NOT_TENURED);
// Returns true if this table has sufficient capacity for adding n elements.
bool HasSufficientCapacity(int n);
// Sets the capacity of the hash table.
void SetCapacity(int capacity) {
// To scale a computed hash code to fit within the hash table, we
......@@ -3420,6 +3423,9 @@ class Dictionary: public HashTable<Derived, Shape, Key> {
int at_least_space_for,
PretenureFlag pretenure = NOT_TENURED);
// Ensures that a new dictionary is created when the capacity is checked.
void SetRequiresCopyOnCapacityChange();
// Ensure enough space for n additional elements.
static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
......
......@@ -228,4 +228,18 @@ TEST(ObjectHashTableCausesGC) {
}
#endif
TEST(SetRequiresCopyOnCapacityChange) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
Isolate* isolate = CcTest::i_isolate();
Handle<NameDictionary> dict = NameDictionary::New(isolate, 0, TENURED);
dict->SetRequiresCopyOnCapacityChange();
Handle<Name> key = isolate->factory()->InternalizeString(
v8::Utils::OpenHandle(*v8_str("key")));
Handle<Object> value = handle(Smi::FromInt(0), isolate);
Handle<NameDictionary> new_dict =
NameDictionary::Add(dict, key, value, PropertyDetails::Empty());
CHECK_NE(*dict, *new_dict);
}
} // namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment