From d9c80d47714d65fae9322ef3f5159ac01eee61d0 Mon Sep 17 00:00:00 2001 From: "vegorov@chromium.org" Date: Mon, 9 May 2011 16:15:18 +0000 Subject: [PATCH] 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 --- src/arm/code-stubs-arm.cc | 19 ++++++++++------- src/arm/code-stubs-arm.h | 15 +++++++------ src/arm/macro-assembler-arm.cc | 11 ++++++++++ src/arm/macro-assembler-arm.h | 5 +++++ src/arm/stub-cache-arm.cc | 48 +++++++++++++++++++++++++----------------- src/ia32/code-stubs-ia32.cc | 17 +++++++++------ src/ia32/code-stubs-ia32.h | 13 ++++++------ src/ia32/stub-cache-ia32.cc | 46 ++++++++++++++++++++++++---------------- src/x64/code-stubs-x64.cc | 17 +++++++++------ src/x64/code-stubs-x64.h | 13 ++++++------ src/x64/stub-cache-x64.cc | 47 +++++++++++++++++++++++++---------------- 11 files changed, 155 insertions(+), 96 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 0c4675e..730677d 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -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(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; } diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h index 112503f..5bc1355 100644 --- a/src/arm/code-stubs-arm.h +++ b/src/arm/code-stubs-arm.h @@ -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, diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc index 3f2b01e..889e981 100644 --- a/src/arm/macro-assembler-arm.cc +++ b/src/arm/macro-assembler-arm.cc @@ -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::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); diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h index ca6b015..8e8409d 100644 --- a/src/arm/macro-assembler-arm.h +++ b/src/arm/macro-assembler-arm.h @@ -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); diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index 6fd5063..7a3c80f 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -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)); diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 3c0042da..0bcbf4b 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -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(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; } diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h index 768bfea..78e6a6d 100644 --- a/src/ia32/code-stubs-ia32.h +++ b/src/ia32/code-stubs-ia32.h @@ -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, diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 30e9dee..56168ea 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -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)); diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 27e6576..6b1cf95 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -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(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; } diff --git a/src/x64/code-stubs-x64.h b/src/x64/code-stubs-x64.h index 44e2775..4e54cea 100644 --- a/src/x64/code-stubs-x64.h +++ b/src/x64/code-stubs-x64.h @@ -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, diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index 6c83606..c3da98e 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -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)); -- 2.7.4