Commit 071d03a4 authored by jkummerow's avatar jkummerow Committed by Commit bot

Add instrumentation to track down a crasher

LoadICs must always return a JS-accessible value (nothing internal).
Dictionary property keys are guaranteed to be unique names.

BUG=chromium:527994
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#30683}
parent 0cc8eaa4
......@@ -2243,10 +2243,46 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
Literal* key = prop->key()->AsLiteral();
DCHECK(!prop->IsSuperAccess());
// See comment below.
if (FeedbackVector()->GetIndex(prop->PropertyFeedbackSlot()) == 6) {
__ Push(LoadDescriptor::ReceiverRegister());
}
__ Move(LoadDescriptor::NameRegister(), key->value());
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallLoadIC(NOT_INSIDE_TYPEOF, language_mode());
// Sanity check: The loaded value must be a JS-exposed kind of object,
// not something internal (like a Map, or FixedArray). Check this here
// to chase after a rare but recurring crash bug. It seems to always
// occur for functions beginning with "this.foo.bar()", so be selective
// and only insert the check for the first LoadIC (identified by slot).
// TODO(jkummerow): Remove this when it has generated a few crash reports.
// Don't forget to remove the Push() above as well!
if (FeedbackVector()->GetIndex(prop->PropertyFeedbackSlot()) == 6) {
__ Pop(LoadDescriptor::ReceiverRegister());
Label ok;
__ JumpIfSmi(rax, &ok, Label::kNear);
__ movp(rbx, FieldOperand(rax, HeapObject::kMapOffset));
__ CmpInstanceType(rbx, LAST_PRIMITIVE_TYPE);
__ j(below_equal, &ok, Label::kNear);
__ CmpInstanceType(rbx, FIRST_JS_RECEIVER_TYPE);
__ j(above_equal, &ok, Label::kNear);
__ Push(Smi::FromInt(0xaabbccdd));
__ Push(LoadDescriptor::ReceiverRegister());
__ movp(rbx, FieldOperand(LoadDescriptor::ReceiverRegister(),
HeapObject::kMapOffset));
__ Push(rbx);
__ movp(rbx, FieldOperand(LoadDescriptor::ReceiverRegister(),
JSObject::kPropertiesOffset));
__ Push(rbx);
__ int3();
__ bind(&ok);
}
}
......
......@@ -2377,6 +2377,17 @@ RUNTIME_FUNCTION(Runtime_LoadIC_Miss) {
LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
// Sanity check: The loaded value must be a JS-exposed kind of object,
// not something internal (like a Map, or FixedArray). Check this here
// to chase after a rare but recurring crash bug.
// TODO(jkummerow): Remove this when it has generated a few crash reports.
if (!result->IsSmi()) {
InstanceType type =
Handle<HeapObject>::cast(result)->map()->instance_type();
CHECK(type <= LAST_PRIMITIVE_TYPE || type >= FIRST_JS_RECEIVER_TYPE);
}
} else {
DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
KeyedLoadICNexus nexus(vector, vector_slot);
......@@ -3115,6 +3126,17 @@ RUNTIME_FUNCTION(Runtime_LoadIC_MissFromStubFailure) {
LoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
// Sanity check: The loaded value must be a JS-exposed kind of object,
// not something internal (like a Map, or FixedArray). Check this here
// to chase after a rare but recurring crash bug.
// TODO(jkummerow): Remove this when it has generated a few crash reports.
if (!result->IsSmi()) {
InstanceType type =
Handle<HeapObject>::cast(result)->map()->instance_type();
CHECK(type <= LAST_PRIMITIVE_TYPE || type >= FIRST_JS_RECEIVER_TYPE);
}
} else {
DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
KeyedLoadICNexus nexus(vector, vector_slot);
......
......@@ -5001,16 +5001,12 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
int index = Smi::cast(iteration_order->get(i))->value();
Object* k = dictionary->KeyAt(index);
DCHECK(dictionary->IsKey(k));
// Dictionary keys are internalized upon insertion.
// TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild.
CHECK(k->IsUniqueName());
Handle<Name> key(Name::cast(k), isolate);
Object* value = dictionary->ValueAt(index);
Handle<Name> key;
if (k->IsSymbol()) {
key = handle(Symbol::cast(k));
} else {
// Ensure the key is a unique name before writing into the
// instance descriptor.
key = factory->InternalizeString(handle(String::cast(k)));
}
PropertyDetails details = dictionary->DetailsAt(index);
int enumeration_index = details.dictionary_index();
......
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