| Index: src/isolate.cc
|
| diff --git a/src/isolate.cc b/src/isolate.cc
|
| index 34b96730103894efcf4e026ae5e682ea0d9df764..eebfc3a194646de27cfb85ef6430c7b198a19298 100644
|
| --- a/src/isolate.cc
|
| +++ b/src/isolate.cc
|
| @@ -2375,29 +2375,91 @@
|
|
|
|
|
| bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
|
| + Handle<PropertyCell> no_elements_cell =
|
| + handle(heap()->array_protector(), this);
|
| + bool cell_reports_intact = no_elements_cell->value()->IsSmi() &&
|
| + Smi::cast(no_elements_cell->value())->value() == 1;
|
| +
|
| +#ifdef DEBUG
|
| Map* root_array_map =
|
| get_initial_js_array_map(GetInitialFastElementsKind());
|
| - DCHECK(root_array_map != NULL);
|
| JSObject* initial_array_proto = JSObject::cast(*initial_array_prototype());
|
| + JSObject* initial_object_proto = JSObject::cast(*initial_object_prototype());
|
| +
|
| + if (root_array_map == NULL || initial_array_proto == initial_object_proto) {
|
| + // We are in the bootstrapping process, and the entire check sequence
|
| + // shouldn't be performed.
|
| + return cell_reports_intact;
|
| + }
|
|
|
| // Check that the array prototype hasn't been altered WRT empty elements.
|
| - if (root_array_map->prototype() != initial_array_proto) return false;
|
| + if (root_array_map->prototype() != initial_array_proto) {
|
| + DCHECK_EQ(false, cell_reports_intact);
|
| + return cell_reports_intact;
|
| + }
|
| +
|
| if (initial_array_proto->elements() != heap()->empty_fixed_array()) {
|
| - return false;
|
| + DCHECK_EQ(false, cell_reports_intact);
|
| + return cell_reports_intact;
|
| }
|
|
|
| // Check that the object prototype hasn't been altered WRT empty elements.
|
| - JSObject* initial_object_proto = JSObject::cast(*initial_object_prototype());
|
| PrototypeIterator iter(this, initial_array_proto);
|
| if (iter.IsAtEnd() || iter.GetCurrent() != initial_object_proto) {
|
| - return false;
|
| + DCHECK_EQ(false, cell_reports_intact);
|
| + return cell_reports_intact;
|
| }
|
| if (initial_object_proto->elements() != heap()->empty_fixed_array()) {
|
| - return false;
|
| + DCHECK_EQ(false, cell_reports_intact);
|
| + return cell_reports_intact;
|
| }
|
|
|
| iter.Advance();
|
| - return iter.IsAtEnd();
|
| + if (!iter.IsAtEnd()) {
|
| + DCHECK_EQ(false, cell_reports_intact);
|
| + return cell_reports_intact;
|
| + }
|
| +
|
| +#endif
|
| +
|
| + return cell_reports_intact;
|
| +}
|
| +
|
| +
|
| +void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) {
|
| + Handle<PropertyCell> array_protector = factory()->array_protector();
|
| + if (IsFastArrayConstructorPrototypeChainIntact() &&
|
| + object->map()->is_prototype_map()) {
|
| + Object* context = heap()->native_contexts_list();
|
| + while (!context->IsUndefined()) {
|
| + Context* current_context = Context::cast(context);
|
| + if (current_context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX) ==
|
| + *object ||
|
| + current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ==
|
| + *object) {
|
| + PropertyCell::SetValueWithInvalidation(array_protector,
|
| + handle(Smi::FromInt(0), this));
|
| + break;
|
| + }
|
| + context = current_context->get(Context::NEXT_CONTEXT_LINK);
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
|
| + if (array->map()->is_prototype_map()) {
|
| + Object* context = heap()->native_contexts_list();
|
| + while (!context->IsUndefined()) {
|
| + Context* current_context = Context::cast(context);
|
| + if (current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ==
|
| + *array) {
|
| + return true;
|
| + }
|
| + context = current_context->get(Context::NEXT_CONTEXT_LINK);
|
| + }
|
| + }
|
| + return false;
|
| }
|
|
|
|
|
|
|