Commit d9c80d47 authored by vegorov@chromium.org's avatar vegorov@chromium.org

Propagate a Failure from GenerateDictionaryNegativeLookup instead of causing GC.

Review URL: http://codereview.chromium.org/6973001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7829 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8033be88
......@@ -6134,13 +6134,14 @@ void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
}
void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
Label* miss,
Label* done,
Register receiver,
Register properties,
String* name,
Register scratch0) {
MaybeObject* StringDictionaryLookupStub::GenerateNegativeLookup(
MacroAssembler* masm,
Label* miss,
Label* done,
Register receiver,
Register properties,
String* name,
Register scratch0) {
// If names of slots in range from 1 to kProbes - 1 for the hash value are
// not equal to the name and kProbes-th slot is not used (its name is the
// undefined value), it guarantees the hash table doesn't contain the
......@@ -6198,12 +6199,14 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
__ ldr(r0, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
__ mov(r1, Operand(Handle<String>(name)));
StringDictionaryLookupStub stub(NEGATIVE_LOOKUP);
__ CallStub(&stub);
MaybeObject* result = masm->TryCallStub(&stub);
if (result->IsFailure()) return result;
__ tst(r0, Operand(r0));
__ ldm(ia_w, sp, spill_mask);
__ b(eq, done);
__ b(ne, miss);
return result;
}
......
......@@ -620,13 +620,14 @@ class StringDictionaryLookupStub: public CodeStub {
void Generate(MacroAssembler* masm);
static void GenerateNegativeLookup(MacroAssembler* masm,
Label* miss,
Label* done,
Register receiver,
Register properties,
String* name,
Register scratch0) ;
MUST_USE_RESULT static MaybeObject* GenerateNegativeLookup(
MacroAssembler* masm,
Label* miss,
Label* done,
Register receiver,
Register properties,
String* name,
Register scratch0);
static void GeneratePositiveLookup(MacroAssembler* masm,
Label* miss,
......
......@@ -1734,6 +1734,17 @@ void MacroAssembler::CallStub(CodeStub* stub, Condition cond) {
}
MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub, Condition cond) {
ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs.
Object* result;
{ MaybeObject* maybe_result = stub->TryGetCode();
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET, cond);
return result;
}
void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) {
ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs.
Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
......
......@@ -702,6 +702,11 @@ class MacroAssembler: public Assembler {
// Call a code stub.
void CallStub(CodeStub* stub, Condition cond = al);
// Call a code stub and return the code object called. Try to generate
// the code if necessary. Do not perform a GC but instead return a retry
// after GC failure.
MUST_USE_RESULT MaybeObject* TryCallStub(CodeStub* stub, Condition cond = al);
// Call a code stub.
void TailCallStub(CodeStub* stub, Condition cond = al);
......
......@@ -95,12 +95,13 @@ static void ProbeTable(Isolate* isolate,
// must always call a backup property check that is complete.
// This function is safe to call if the receiver has fast properties.
// Name must be a symbol and receiver must be a heap object.
static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
Label* miss_label,
Register receiver,
String* name,
Register scratch0,
Register scratch1) {
MUST_USE_RESULT static MaybeObject* GenerateDictionaryNegativeLookup(
MacroAssembler* masm,
Label* miss_label,
Register receiver,
String* name,
Register scratch0,
Register scratch1) {
ASSERT(name->IsSymbol());
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
......@@ -137,16 +138,20 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
__ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
StringDictionaryLookupStub::GenerateNegativeLookup(masm,
miss_label,
&done,
receiver,
properties,
name,
scratch1);
MaybeObject* result = StringDictionaryLookupStub::GenerateNegativeLookup(
masm,
miss_label,
&done,
receiver,
properties,
name,
scratch1);
if (result->IsFailure()) return result;
__ bind(&done);
__ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
return result;
}
......@@ -1048,12 +1053,17 @@ Register StubCompiler::CheckPrototypes(JSObject* object,
ASSERT(current->property_dictionary()->FindEntry(name) ==
StringDictionary::kNotFound);
GenerateDictionaryNegativeLookup(masm(),
miss,
reg,
name,
scratch1,
scratch2);
MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(),
miss,
reg,
name,
scratch1,
scratch2);
if (negative_lookup->IsFailure()) {
set_failure(Failure::cast(negative_lookup));
return reg;
}
__ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
reg = holder_reg; // from now the object is in holder_reg
__ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
......
......@@ -6035,12 +6035,13 @@ void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
// must always call a backup property check that is complete.
// This function is safe to call if the receiver has fast properties.
// Name must be a symbol and receiver must be a heap object.
void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
Label* miss,
Label* done,
Register properties,
String* name,
Register r0) {
MaybeObject* StringDictionaryLookupStub::GenerateNegativeLookup(
MacroAssembler* masm,
Label* miss,
Label* done,
Register properties,
String* name,
Register r0) {
ASSERT(name->IsSymbol());
// If names of slots in range from 1 to kProbes - 1 for the hash value are
......@@ -6086,10 +6087,12 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
StringDictionaryLookupStub::NEGATIVE_LOOKUP);
__ push(Immediate(Handle<Object>(name)));
__ push(Immediate(name->Hash()));
__ CallStub(&stub);
MaybeObject* result = masm->TryCallStub(&stub);
if (result->IsFailure()) return result;
__ test(r0, Operand(r0));
__ j(not_zero, miss);
__ jmp(done);
return result;
}
......
......@@ -449,12 +449,13 @@ class StringDictionaryLookupStub: public CodeStub {
void Generate(MacroAssembler* masm);
static void GenerateNegativeLookup(MacroAssembler* masm,
Label* miss,
Label* done,
Register properties,
String* name,
Register r0);
MUST_USE_RESULT static MaybeObject* GenerateNegativeLookup(
MacroAssembler* masm,
Label* miss,
Label* done,
Register properties,
String* name,
Register r0);
static void GeneratePositiveLookup(MacroAssembler* masm,
Label* miss,
......
......@@ -107,12 +107,12 @@ static void ProbeTable(Isolate* isolate,
// must always call a backup property check that is complete.
// This function is safe to call if the receiver has fast properties.
// Name must be a symbol and receiver must be a heap object.
static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
Label* miss_label,
Register receiver,
String* name,
Register r0,
Register r1) {
static MaybeObject* GenerateDictionaryNegativeLookup(MacroAssembler* masm,
Label* miss_label,
Register receiver,
String* name,
Register r0,
Register r1) {
ASSERT(name->IsSymbol());
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->negative_lookups(), 1);
......@@ -142,14 +142,19 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
__ j(not_equal, miss_label);
Label done;
StringDictionaryLookupStub::GenerateNegativeLookup(masm,
miss_label,
&done,
properties,
name,
r1);
MaybeObject* result =
StringDictionaryLookupStub::GenerateNegativeLookup(masm,
miss_label,
&done,
properties,
name,
r1);
if (result->IsFailure()) return result;
__ bind(&done);
__ DecrementCounter(counters->negative_lookups_miss(), 1);
return result;
}
......@@ -901,12 +906,17 @@ Register StubCompiler::CheckPrototypes(JSObject* object,
ASSERT(current->property_dictionary()->FindEntry(name) ==
StringDictionary::kNotFound);
GenerateDictionaryNegativeLookup(masm(),
miss,
reg,
name,
scratch1,
scratch2);
MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(),
miss,
reg,
name,
scratch1,
scratch2);
if (negative_lookup->IsFailure()) {
set_failure(Failure::cast(negative_lookup));
return reg;
}
__ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
reg = holder_reg; // from now the object is in holder_reg
__ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
......
......@@ -4907,12 +4907,13 @@ void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
}
void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
Label* miss,
Label* done,
Register properties,
String* name,
Register r0) {
MaybeObject* StringDictionaryLookupStub::GenerateNegativeLookup(
MacroAssembler* masm,
Label* miss,
Label* done,
Register properties,
String* name,
Register r0) {
// If names of slots in range from 1 to kProbes - 1 for the hash value are
// not equal to the name and kProbes-th slot is not used (its name is the
// undefined value), it guarantees the hash table doesn't contain the
......@@ -4959,10 +4960,12 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
StringDictionaryLookupStub::NEGATIVE_LOOKUP);
__ Push(Handle<Object>(name));
__ push(Immediate(name->Hash()));
__ CallStub(&stub);
MaybeObject* result = masm->TryCallStub(&stub);
if (result->IsFailure()) return result;
__ testq(r0, r0);
__ j(not_zero, miss);
__ jmp(done);
return result;
}
......
......@@ -446,12 +446,13 @@ class StringDictionaryLookupStub: public CodeStub {
void Generate(MacroAssembler* masm);
static void GenerateNegativeLookup(MacroAssembler* masm,
Label* miss,
Label* done,
Register properties,
String* name,
Register r0);
MUST_USE_RESULT static MaybeObject* GenerateNegativeLookup(
MacroAssembler* masm,
Label* miss,
Label* done,
Register properties,
String* name,
Register r0);
static void GeneratePositiveLookup(MacroAssembler* masm,
Label* miss,
......
......@@ -82,12 +82,13 @@ static void ProbeTable(Isolate* isolate,
// must always call a backup property check that is complete.
// This function is safe to call if the receiver has fast properties.
// Name must be a symbol and receiver must be a heap object.
static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
Label* miss_label,
Register receiver,
String* name,
Register r0,
Register r1) {
MUST_USE_RESULT static MaybeObject* GenerateDictionaryNegativeLookup(
MacroAssembler* masm,
Label* miss_label,
Register receiver,
String* name,
Register r0,
Register r1) {
ASSERT(name->IsSymbol());
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->negative_lookups(), 1);
......@@ -117,14 +118,19 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
__ j(not_equal, miss_label);
Label done;
StringDictionaryLookupStub::GenerateNegativeLookup(masm,
miss_label,
&done,
properties,
name,
r1);
MaybeObject* result = StringDictionaryLookupStub::GenerateNegativeLookup(
masm,
miss_label,
&done,
properties,
name,
r1);
if (result->IsFailure()) return result;
__ bind(&done);
__ DecrementCounter(counters->negative_lookups_miss(), 1);
return result;
}
......@@ -857,12 +863,17 @@ Register StubCompiler::CheckPrototypes(JSObject* object,
ASSERT(current->property_dictionary()->FindEntry(name) ==
StringDictionary::kNotFound);
GenerateDictionaryNegativeLookup(masm(),
miss,
reg,
name,
scratch1,
scratch2);
MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(),
miss,
reg,
name,
scratch1,
scratch2);
if (negative_lookup->IsFailure()) {
set_failure(Failure::cast(negative_lookup));
return reg;
}
__ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
reg = holder_reg; // from now the object is in holder_reg
__ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
......
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