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::use_crankshaft() const { |
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; |
} |