Chromium Code Reviews| Index: src/isolate.cc |
| diff --git a/src/isolate.cc b/src/isolate.cc |
| index 34b96730103894efcf4e026ae5e682ea0d9df764..41ae0ba5c6e6cff3d16b8077a2b8f3c0e7aaea0b 100644 |
| --- a/src/isolate.cc |
| +++ b/src/isolate.cc |
| @@ -2375,29 +2375,92 @@ 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) { |
| + PrintF("INVALIDATING YOU!!!\n"); |
|
Jakob Kummerow
2015/04/22 08:02:20
yeah...
mvstanton
2015/04/22 09:39:07
I've discovered a bit of drama livens up the workd
|
| + 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; |
| } |