From a81b05af931451e1aac104758a11aa50893ab30f Mon Sep 17 00:00:00 2001 From: "erik.corry@gmail.com" Date: Tue, 28 Feb 2012 08:32:44 +0000 Subject: [PATCH] Fix the negative lookup stub to handle deleted entries in a dictionary. This fixes http://code.google.com/p/v8/issues/detail?id=1964 "Closure-uri benchmark is sensitive to hash seed". Review URL: https://chromiumcodereview.appspot.com/9463012 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10848 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 11 ++++++++++- src/ia32/code-stubs-ia32.cc | 8 +++++++- src/mips/code-stubs-mips.cc | 10 +++++++++- src/x64/code-stubs-x64.cc | 9 ++++++++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 62e6c8027..25563ed02 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -6812,7 +6812,7 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, // 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 // property. It's true even if some slots represent deleted properties - // (their names are the null value). + // (their names are the hole value). for (int i = 0; i < kInlinedProbes; i++) { // scratch0 points to properties hash. // Compute the masked index: (hash + i + i * i) & mask. @@ -6840,10 +6840,17 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ b(eq, done); if (i != kInlinedProbes - 1) { + // Load the hole ready for use below: + __ LoadRoot(tmp, Heap::kTheHoleValueRootIndex); + // Stop if found the property. __ cmp(entity_name, Operand(Handle(name))); __ b(eq, miss); + Label the_hole; + __ cmp(entity_name, tmp); + __ b(eq, &the_hole); + // Check if the entry name is not a symbol. __ ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); __ ldrb(entity_name, @@ -6851,6 +6858,8 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ tst(entity_name, Operand(kIsSymbolMask)); __ b(eq, miss); + __ bind(&the_hole); + // Restore the properties. __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 2d078cdc0..864e76c8d 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -6823,7 +6823,7 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, // 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 // property. It's true even if some slots represent deleted properties - // (their names are the null value). + // (their names are the hole value). for (int i = 0; i < kInlinedProbes; i++) { // Compute the masked index: (hash + i + i * i) & mask. Register index = r0; @@ -6849,11 +6849,17 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ cmp(entity_name, Handle(name)); __ j(equal, miss); + Label the_hole; + // Check for the hole and skip. + __ cmp(entity_name, masm->isolate()->factory()->the_hole_value()); + __ j(equal, &the_hole, Label::kNear); + // Check if the entry name is not a symbol. __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset), kIsSymbolMask); __ j(zero, miss); + __ bind(&the_hole); } StringDictionaryLookupStub stub(properties, diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index de6fb953c..6f7922526 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -7070,7 +7070,7 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, // 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 // property. It's true even if some slots represent deleted properties - // (their names are the null value). + // (their names are the hole value). for (int i = 0; i < kInlinedProbes; i++) { // scratch0 points to properties hash. // Compute the masked index: (hash + i + i * i) & mask. @@ -7099,9 +7099,15 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ Branch(done, eq, entity_name, Operand(tmp)); if (i != kInlinedProbes - 1) { + // Load the hole ready for use below: + __ LoadRoot(tmp, Heap::kTheHoleValueRootIndex); + // Stop if found the property. __ Branch(miss, eq, entity_name, Operand(Handle(name))); + Label the_hole; + __ Branch(&the_hole, eq, entity_name, Operand(tmp)); + // Check if the entry name is not a symbol. __ lw(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); __ lbu(entity_name, @@ -7109,6 +7115,8 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ And(scratch0, entity_name, Operand(kIsSymbolMask)); __ Branch(miss, eq, scratch0, Operand(zero_reg)); + __ bind(&the_hole); + // Restore the properties. __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 61404fa2d..5587609dd 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -5753,7 +5753,7 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, // 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 // property. It's true even if some slots represent deleted properties - // (their names are the null value). + // (their names are the hole value). for (int i = 0; i < kInlinedProbes; i++) { // r0 points to properties hash. // Compute the masked index: (hash + i + i * i) & mask. @@ -5782,11 +5782,18 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ Cmp(entity_name, Handle(name)); __ j(equal, miss); + Label the_hole; + // Check for the hole and skip. + __ CompareRoot(entity_name, Heap::kTheHoleValueRootIndex); + __ j(equal, &the_hole, Label::kNear); + // Check if the entry name is not a symbol. __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), Immediate(kIsSymbolMask)); __ j(zero, miss); + + __ bind(&the_hole); } StringDictionaryLookupStub stub(properties, -- 2.34.1