Commit 4d736273 authored by rossberg@chromium.org's avatar rossberg@chromium.org

Handlify JSObject::SetDictionaryElement, which may call back into JS.

Fixes flaky crasher in proxies.js test.

R=mstarzinger@chromium.org
BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13169 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 125b1c29
...@@ -10142,7 +10142,7 @@ MaybeObject* JSObject::SetFastElement(uint32_t index, ...@@ -10142,7 +10142,7 @@ MaybeObject* JSObject::SetFastElement(uint32_t index,
MaybeObject* JSObject::SetDictionaryElement(uint32_t index, MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
Object* value, Object* value_raw,
PropertyAttributes attributes, PropertyAttributes attributes,
StrictModeFlag strict_mode, StrictModeFlag strict_mode,
bool check_prototype, bool check_prototype,
...@@ -10150,24 +10150,23 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index, ...@@ -10150,24 +10150,23 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
Isolate* isolate = GetIsolate(); Isolate* isolate = GetIsolate();
Heap* heap = isolate->heap(); Heap* heap = isolate->heap();
Handle<JSObject> self(this);
Handle<Object> value(value_raw);
// Insert element in the dictionary. // Insert element in the dictionary.
FixedArray* elements = FixedArray::cast(this->elements()); Handle<FixedArray> elements(FixedArray::cast(this->elements()));
bool is_arguments = bool is_arguments =
(elements->map() == heap->non_strict_arguments_elements_map()); (elements->map() == heap->non_strict_arguments_elements_map());
SeededNumberDictionary* dictionary = NULL; Handle<SeededNumberDictionary> dictionary(is_arguments
if (is_arguments) { ? SeededNumberDictionary::cast(elements->get(1))
dictionary = SeededNumberDictionary::cast(elements->get(1)); : SeededNumberDictionary::cast(*elements));
} else {
dictionary = SeededNumberDictionary::cast(elements);
}
int entry = dictionary->FindEntry(index); int entry = dictionary->FindEntry(index);
if (entry != SeededNumberDictionary::kNotFound) { if (entry != SeededNumberDictionary::kNotFound) {
Object* element = dictionary->ValueAt(entry); Object* element = dictionary->ValueAt(entry);
PropertyDetails details = dictionary->DetailsAt(entry); PropertyDetails details = dictionary->DetailsAt(entry);
if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) {
return SetElementWithCallback(element, index, value, this, strict_mode); return SetElementWithCallback(element, index, *value, this, strict_mode);
} else { } else {
dictionary->UpdateMaxNumberKey(index); dictionary->UpdateMaxNumberKey(index);
// If a value has not been initialized we allow writing to it even if it // If a value has not been initialized we allow writing to it even if it
...@@ -10196,24 +10195,24 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index, ...@@ -10196,24 +10195,24 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
Context* context = Context::cast(elements->get(0)); Context* context = Context::cast(elements->get(0));
int context_index = entry->aliased_context_slot(); int context_index = entry->aliased_context_slot();
ASSERT(!context->get(context_index)->IsTheHole()); ASSERT(!context->get(context_index)->IsTheHole());
context->set(context_index, value); context->set(context_index, *value);
// For elements that are still writable we keep slow aliasing. // For elements that are still writable we keep slow aliasing.
if (!details.IsReadOnly()) value = element; if (!details.IsReadOnly()) value = handle(element, isolate);
} }
dictionary->ValueAtPut(entry, value); dictionary->ValueAtPut(entry, *value);
} }
} else { } else {
// Index not already used. Look for an accessor in the prototype chain. // Index not already used. Look for an accessor in the prototype chain.
// Can cause GC!
if (check_prototype) { if (check_prototype) {
bool found; bool found;
MaybeObject* result = MaybeObject* result = SetElementWithCallbackSetterInPrototypes(
SetElementWithCallbackSetterInPrototypes( index, *value, &found, strict_mode);
index, value, &found, strict_mode);
if (found) return result; if (found) return result;
} }
// When we set the is_extensible flag to false we always force the // When we set the is_extensible flag to false we always force the
// element into dictionary mode (and force them to stay there). // element into dictionary mode (and force them to stay there).
if (!map()->is_extensible()) { if (!self->map()->is_extensible()) {
if (strict_mode == kNonStrictMode) { if (strict_mode == kNonStrictMode) {
return isolate->heap()->undefined_value(); return isolate->heap()->undefined_value();
} else { } else {
...@@ -10228,30 +10227,31 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index, ...@@ -10228,30 +10227,31 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
} }
FixedArrayBase* new_dictionary; FixedArrayBase* new_dictionary;
PropertyDetails details = PropertyDetails(attributes, NORMAL); PropertyDetails details = PropertyDetails(attributes, NORMAL);
MaybeObject* maybe = dictionary->AddNumberEntry(index, value, details); MaybeObject* maybe = dictionary->AddNumberEntry(index, *value, details);
if (!maybe->To(&new_dictionary)) return maybe; if (!maybe->To(&new_dictionary)) return maybe;
if (dictionary != SeededNumberDictionary::cast(new_dictionary)) { if (*dictionary != SeededNumberDictionary::cast(new_dictionary)) {
if (is_arguments) { if (is_arguments) {
elements->set(1, new_dictionary); elements->set(1, new_dictionary);
} else { } else {
set_elements(new_dictionary); self->set_elements(new_dictionary);
} }
dictionary = SeededNumberDictionary::cast(new_dictionary); dictionary =
handle(SeededNumberDictionary::cast(new_dictionary), isolate);
} }
} }
// Update the array length if this JSObject is an array. // Update the array length if this JSObject is an array.
if (IsJSArray()) { if (self->IsJSArray()) {
MaybeObject* result = MaybeObject* result =
JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value); JSArray::cast(*self)->JSArrayUpdateLengthFromIndex(index, *value);
if (result->IsFailure()) return result; if (result->IsFailure()) return result;
} }
// Attempt to put this object back in fast case. // Attempt to put this object back in fast case.
if (ShouldConvertToFastElements()) { if (self->ShouldConvertToFastElements()) {
uint32_t new_length = 0; uint32_t new_length = 0;
if (IsJSArray()) { if (self->IsJSArray()) {
CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); CHECK(JSArray::cast(*self)->length()->ToArrayIndex(&new_length));
} else { } else {
new_length = dictionary->max_number_key() + 1; new_length = dictionary->max_number_key() + 1;
} }
...@@ -10260,16 +10260,15 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index, ...@@ -10260,16 +10260,15 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
: kDontAllowSmiElements; : kDontAllowSmiElements;
bool has_smi_only_elements = false; bool has_smi_only_elements = false;
bool should_convert_to_fast_double_elements = bool should_convert_to_fast_double_elements =
ShouldConvertToFastDoubleElements(&has_smi_only_elements); self->ShouldConvertToFastDoubleElements(&has_smi_only_elements);
if (has_smi_only_elements) { if (has_smi_only_elements) {
smi_mode = kForceSmiElements; smi_mode = kForceSmiElements;
} }
MaybeObject* result = should_convert_to_fast_double_elements MaybeObject* result = should_convert_to_fast_double_elements
? SetFastDoubleElementsCapacityAndLength(new_length, new_length) ? self->SetFastDoubleElementsCapacityAndLength(new_length, new_length)
: SetFastElementsCapacityAndLength(new_length, : self->SetFastElementsCapacityAndLength(
new_length, new_length, new_length, smi_mode);
smi_mode); self->ValidateElements();
ValidateElements();
if (result->IsFailure()) return result; if (result->IsFailure()) return result;
#ifdef DEBUG #ifdef DEBUG
if (FLAG_trace_normalization) { if (FLAG_trace_normalization) {
...@@ -10278,7 +10277,7 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index, ...@@ -10278,7 +10277,7 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
} }
#endif #endif
} }
return value; return *value;
} }
......
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