Index: src/isolate.cc |
diff --git a/src/isolate.cc b/src/isolate.cc |
index a8e1b27039108749da2ac849db49a09a8afbdc18..8eb8b71b39347918cf32ef3c7127e410a3340bd4 100644 |
--- a/src/isolate.cc |
+++ b/src/isolate.cc |
@@ -2511,8 +2511,35 @@ bool Isolate::IsFastArrayConstructorPrototypeChainIntact() { |
return cell_reports_intact; |
} |
+bool Isolate::IsArraySpeciesLookupChainIntact() { |
+ // Note: It would be nice to have debug checks to make sure that the |
+ // species protector is accurate, but this would be hard to do for most of |
+ // what the protector stands for: |
+ // - You'd need to traverse the heap to check that no Array instance has |
+ // a constructor property or a modified __proto__ |
+ // - To check that Array[Symbol.species] == Array, JS code has to execute, |
+ // but JS cannot be invoked in callstack overflow situations |
+ // All that could be checked reliably is that |
+ // Array.prototype.constructor == Array. Given that limitation, no check is |
+ // done here. In place, there are mjsunit tests harmony/array-species* which |
+ // ensure that behavior is correct in various invalid protector cases. |
+ |
+ PropertyCell* species_cell = heap()->species_protector(); |
+ return species_cell->value()->IsSmi() && |
+ Smi::cast(species_cell->value())->value() == kArrayProtectorValid; |
+} |
+ |
+void Isolate::InvalidateArraySpeciesProtector() { |
+ DCHECK(factory()->species_protector()->value()->IsSmi()); |
+ DCHECK(IsArraySpeciesLookupChainIntact()); |
+ PropertyCell::SetValueWithInvalidation( |
+ factory()->species_protector(), |
+ handle(Smi::FromInt(kArrayProtectorInvalid), this)); |
+ DCHECK(!IsArraySpeciesLookupChainIntact()); |
+} |
void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) { |
+ DisallowHeapAllocation no_gc; |
if (IsFastArrayConstructorPrototypeChainIntact() && |
object->map()->is_prototype_map()) { |
Object* context = heap()->native_contexts_list(); |
@@ -2522,6 +2549,7 @@ void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) { |
*object || |
current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) == |
*object) { |
+ CountUsage(v8::Isolate::UseCounterFeature::kArrayProtectorDirtied); |
PropertyCell::SetValueWithInvalidation( |
factory()->array_protector(), |
handle(Smi::FromInt(kArrayProtectorInvalid), this)); |