Commit ffcc4de0 authored by palfia@homejinni.com's avatar palfia@homejinni.com

MIPS: ES6 symbols: Allow symbols as property names

Port r13811 (0e64f280)

Original commit message:
Since symbols and strings share a common representation, most of this change is about consistently replacing 'String' with 'Name' in all places where property names are expected. In particular, no new logic at all is necessary for maps, property dictionaries, or transitions. :) The only places where an actual case distinction is needed have to do with generated type checks, and with conversions of names to strings (especially in logger and profiler).

Left in some TODOs wrt to the API: interceptors and native getters don't accept symbols as property names yet, because that would require extending the external v8.h.

(Baseline CL: https://codereview.chromium.org/12296026/)

BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13874 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8312b895
...@@ -7519,13 +7519,14 @@ void DirectCEntryStub::GenerateCall(MacroAssembler* masm, ...@@ -7519,13 +7519,14 @@ void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
} }
void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
Label* miss, Label* miss,
Label* done, Label* done,
Register receiver, Register receiver,
Register properties, Register properties,
Handle<String> name, Handle<Name> name,
Register scratch0) { Register scratch0) {
ASSERT(name->IsUniqueName());
// If names of slots in range from 1 to kProbes - 1 for the hash value are // 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 // 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 // undefined value), it guarantees the hash table doesn't contain the
...@@ -7539,10 +7540,10 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, ...@@ -7539,10 +7540,10 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
__ lw(index, FieldMemOperand(properties, kCapacityOffset)); __ lw(index, FieldMemOperand(properties, kCapacityOffset));
__ Subu(index, index, Operand(1)); __ Subu(index, index, Operand(1));
__ And(index, index, Operand( __ And(index, index, Operand(
Smi::FromInt(name->Hash() + StringDictionary::GetProbeOffset(i)))); Smi::FromInt(name->Hash() + NameDictionary::GetProbeOffset(i))));
// Scale the index by multiplying by the entry size. // Scale the index by multiplying by the entry size.
ASSERT(StringDictionary::kEntrySize == 3); ASSERT(NameDictionary::kEntrySize == 3);
__ sll(at, index, 1); __ sll(at, index, 1);
__ Addu(index, index, at); __ Addu(index, index, at);
...@@ -7563,19 +7564,20 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, ...@@ -7563,19 +7564,20 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
__ LoadRoot(tmp, Heap::kTheHoleValueRootIndex); __ LoadRoot(tmp, Heap::kTheHoleValueRootIndex);
// Stop if found the property. // Stop if found the property.
__ Branch(miss, eq, entity_name, Operand(Handle<String>(name))); __ Branch(miss, eq, entity_name, Operand(Handle<Name>(name)));
Label the_hole; Label good;
__ Branch(&the_hole, eq, entity_name, Operand(tmp)); __ Branch(&good, eq, entity_name, Operand(tmp));
// Check if the entry name is not a internalized string. // Check if the entry name is not a unique name.
__ lw(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); __ lw(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset));
__ lbu(entity_name, __ lbu(entity_name,
FieldMemOperand(entity_name, Map::kInstanceTypeOffset)); FieldMemOperand(entity_name, Map::kInstanceTypeOffset));
__ And(scratch0, entity_name, Operand(kIsInternalizedMask)); __ And(scratch0, entity_name, Operand(kIsInternalizedMask));
__ Branch(miss, eq, scratch0, Operand(zero_reg)); __ Branch(&good, ne, scratch0, Operand(zero_reg));
__ Branch(miss, ne, entity_name, Operand(SYMBOL_TYPE));
__ bind(&the_hole); __ bind(&good);
// Restore the properties. // Restore the properties.
__ lw(properties, __ lw(properties,
...@@ -7589,8 +7591,8 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, ...@@ -7589,8 +7591,8 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
__ MultiPush(spill_mask); __ MultiPush(spill_mask);
__ lw(a0, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); __ lw(a0, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
__ li(a1, Operand(Handle<String>(name))); __ li(a1, Operand(Handle<Name>(name)));
StringDictionaryLookupStub stub(NEGATIVE_LOOKUP); NameDictionaryLookupStub stub(NEGATIVE_LOOKUP);
__ CallStub(&stub); __ CallStub(&stub);
__ mov(at, v0); __ mov(at, v0);
__ MultiPop(spill_mask); __ MultiPop(spill_mask);
...@@ -7600,11 +7602,11 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, ...@@ -7600,11 +7602,11 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
} }
// Probe the string dictionary in the |elements| register. Jump to the // Probe the name dictionary in the |elements| register. Jump to the
// |done| label if a property with the given name is found. Jump to // |done| label if a property with the given name is found. Jump to
// the |miss| label otherwise. // the |miss| label otherwise.
// If lookup was successful |scratch2| will be equal to elements + 4 * index. // If lookup was successful |scratch2| will be equal to elements + 4 * index.
void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
Label* miss, Label* miss,
Label* done, Label* done,
Register elements, Register elements,
...@@ -7616,7 +7618,7 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, ...@@ -7616,7 +7618,7 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
ASSERT(!name.is(scratch1)); ASSERT(!name.is(scratch1));
ASSERT(!name.is(scratch2)); ASSERT(!name.is(scratch2));
__ AssertString(name); __ AssertName(name);
// Compute the capacity mask. // Compute the capacity mask.
__ lw(scratch1, FieldMemOperand(elements, kCapacityOffset)); __ lw(scratch1, FieldMemOperand(elements, kCapacityOffset));
...@@ -7628,21 +7630,21 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, ...@@ -7628,21 +7630,21 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
// cover ~93% of loads from dictionaries. // cover ~93% of loads from dictionaries.
for (int i = 0; i < kInlinedProbes; i++) { for (int i = 0; i < kInlinedProbes; i++) {
// Compute the masked index: (hash + i + i * i) & mask. // Compute the masked index: (hash + i + i * i) & mask.
__ lw(scratch2, FieldMemOperand(name, String::kHashFieldOffset)); __ lw(scratch2, FieldMemOperand(name, Name::kHashFieldOffset));
if (i > 0) { if (i > 0) {
// Add the probe offset (i + i * i) left shifted to avoid right shifting // Add the probe offset (i + i * i) left shifted to avoid right shifting
// the hash in a separate instruction. The value hash + i + i * i is right // the hash in a separate instruction. The value hash + i + i * i is right
// shifted in the following and instruction. // shifted in the following and instruction.
ASSERT(StringDictionary::GetProbeOffset(i) < ASSERT(NameDictionary::GetProbeOffset(i) <
1 << (32 - String::kHashFieldOffset)); 1 << (32 - Name::kHashFieldOffset));
__ Addu(scratch2, scratch2, Operand( __ Addu(scratch2, scratch2, Operand(
StringDictionary::GetProbeOffset(i) << String::kHashShift)); NameDictionary::GetProbeOffset(i) << Name::kHashShift));
} }
__ srl(scratch2, scratch2, String::kHashShift); __ srl(scratch2, scratch2, Name::kHashShift);
__ And(scratch2, scratch1, scratch2); __ And(scratch2, scratch1, scratch2);
// Scale the index by multiplying by the element size. // Scale the index by multiplying by the element size.
ASSERT(StringDictionary::kEntrySize == 3); ASSERT(NameDictionary::kEntrySize == 3);
// scratch2 = scratch2 * 3. // scratch2 = scratch2 * 3.
__ sll(at, scratch2, 1); __ sll(at, scratch2, 1);
...@@ -7669,7 +7671,7 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, ...@@ -7669,7 +7671,7 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
__ Move(a0, elements); __ Move(a0, elements);
__ Move(a1, name); __ Move(a1, name);
} }
StringDictionaryLookupStub stub(POSITIVE_LOOKUP); NameDictionaryLookupStub stub(POSITIVE_LOOKUP);
__ CallStub(&stub); __ CallStub(&stub);
__ mov(scratch2, a2); __ mov(scratch2, a2);
__ mov(at, v0); __ mov(at, v0);
...@@ -7680,14 +7682,14 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, ...@@ -7680,14 +7682,14 @@ void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
} }
void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { void NameDictionaryLookupStub::Generate(MacroAssembler* masm) {
// This stub overrides SometimesSetsUpAFrame() to return false. That means // This stub overrides SometimesSetsUpAFrame() to return false. That means
// we cannot call anything that could cause a GC from this stub. // we cannot call anything that could cause a GC from this stub.
// Registers: // Registers:
// result: StringDictionary to probe // result: NameDictionary to probe
// a1: key // a1: key
// : StringDictionary to probe. // dictionary: NameDictionary to probe.
// index_: will hold an index of entry if lookup is successful. // index: will hold an index of entry if lookup is successful.
// might alias with result_. // might alias with result_.
// Returns: // Returns:
// result_ is zero if lookup failed, non zero otherwise. // result_ is zero if lookup failed, non zero otherwise.
...@@ -7707,7 +7709,7 @@ void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { ...@@ -7707,7 +7709,7 @@ void StringDictionaryLookupStub::Generate(MacroAssembler* masm) {
__ sra(mask, mask, kSmiTagSize); __ sra(mask, mask, kSmiTagSize);
__ Subu(mask, mask, Operand(1)); __ Subu(mask, mask, Operand(1));
__ lw(hash, FieldMemOperand(key, String::kHashFieldOffset)); __ lw(hash, FieldMemOperand(key, Name::kHashFieldOffset));
__ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex);
...@@ -7718,18 +7720,18 @@ void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { ...@@ -7718,18 +7720,18 @@ void StringDictionaryLookupStub::Generate(MacroAssembler* masm) {
// Add the probe offset (i + i * i) left shifted to avoid right shifting // Add the probe offset (i + i * i) left shifted to avoid right shifting
// the hash in a separate instruction. The value hash + i + i * i is right // the hash in a separate instruction. The value hash + i + i * i is right
// shifted in the following and instruction. // shifted in the following and instruction.
ASSERT(StringDictionary::GetProbeOffset(i) < ASSERT(NameDictionary::GetProbeOffset(i) <
1 << (32 - String::kHashFieldOffset)); 1 << (32 - Name::kHashFieldOffset));
__ Addu(index, hash, Operand( __ Addu(index, hash, Operand(
StringDictionary::GetProbeOffset(i) << String::kHashShift)); NameDictionary::GetProbeOffset(i) << Name::kHashShift));
} else { } else {
__ mov(index, hash); __ mov(index, hash);
} }
__ srl(index, index, String::kHashShift); __ srl(index, index, Name::kHashShift);
__ And(index, mask, index); __ And(index, mask, index);
// Scale the index by multiplying by the entry size. // Scale the index by multiplying by the entry size.
ASSERT(StringDictionary::kEntrySize == 3); ASSERT(NameDictionary::kEntrySize == 3);
// index *= 3. // index *= 3.
__ mov(at, index); __ mov(at, index);
__ sll(index, index, 1); __ sll(index, index, 1);
...@@ -7748,12 +7750,15 @@ void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { ...@@ -7748,12 +7750,15 @@ void StringDictionaryLookupStub::Generate(MacroAssembler* masm) {
__ Branch(&in_dictionary, eq, entry_key, Operand(key)); __ Branch(&in_dictionary, eq, entry_key, Operand(key));
if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
// Check if the entry name is not a internalized string. // Check if the entry name is not a unique name.
Label cont;
__ lw(entry_key, FieldMemOperand(entry_key, HeapObject::kMapOffset)); __ lw(entry_key, FieldMemOperand(entry_key, HeapObject::kMapOffset));
__ lbu(entry_key, __ lbu(entry_key,
FieldMemOperand(entry_key, Map::kInstanceTypeOffset)); FieldMemOperand(entry_key, Map::kInstanceTypeOffset));
__ And(result, entry_key, Operand(kIsInternalizedMask)); __ And(result, entry_key, Operand(kIsInternalizedMask));
__ Branch(&maybe_in_dictionary, eq, result, Operand(zero_reg)); __ Branch(&cont, ne, result, Operand(zero_reg));
__ Branch(&maybe_in_dictionary, ne, entry_key, Operand(SYMBOL_TYPE));
__ bind(&cont);
} }
} }
......
...@@ -739,11 +739,11 @@ class FloatingPointHelper : public AllStatic { ...@@ -739,11 +739,11 @@ class FloatingPointHelper : public AllStatic {
}; };
class StringDictionaryLookupStub: public PlatformCodeStub { class NameDictionaryLookupStub: public PlatformCodeStub {
public: public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
explicit StringDictionaryLookupStub(LookupMode mode) : mode_(mode) { } explicit NameDictionaryLookupStub(LookupMode mode) : mode_(mode) { }
void Generate(MacroAssembler* masm); void Generate(MacroAssembler* masm);
...@@ -752,7 +752,7 @@ class StringDictionaryLookupStub: public PlatformCodeStub { ...@@ -752,7 +752,7 @@ class StringDictionaryLookupStub: public PlatformCodeStub {
Label* done, Label* done,
Register receiver, Register receiver,
Register properties, Register properties,
Handle<String> name, Handle<Name> name,
Register scratch0); Register scratch0);
static void GeneratePositiveLookup(MacroAssembler* masm, static void GeneratePositiveLookup(MacroAssembler* masm,
...@@ -770,14 +770,14 @@ class StringDictionaryLookupStub: public PlatformCodeStub { ...@@ -770,14 +770,14 @@ class StringDictionaryLookupStub: public PlatformCodeStub {
static const int kTotalProbes = 20; static const int kTotalProbes = 20;
static const int kCapacityOffset = static const int kCapacityOffset =
StringDictionary::kHeaderSize + NameDictionary::kHeaderSize +
StringDictionary::kCapacityIndex * kPointerSize; NameDictionary::kCapacityIndex * kPointerSize;
static const int kElementsStartOffset = static const int kElementsStartOffset =
StringDictionary::kHeaderSize + NameDictionary::kHeaderSize +
StringDictionary::kElementsStartIndex * kPointerSize; NameDictionary::kElementsStartIndex * kPointerSize;
Major MajorKey() { return StringDictionaryLookup; } Major MajorKey() { return NameDictionaryLookup; }
int MinorKey() { int MinorKey() {
return LookupModeBits::encode(mode_); return LookupModeBits::encode(mode_);
......
This diff is collapsed.
...@@ -3866,6 +3866,15 @@ void MacroAssembler::IsObjectJSStringType(Register object, ...@@ -3866,6 +3866,15 @@ void MacroAssembler::IsObjectJSStringType(Register object,
} }
void MacroAssembler::IsObjectNameType(Register object,
Register scratch,
Label* fail) {
lw(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
lbu(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
Branch(fail, hi, scratch, Operand(LAST_NAME_TYPE));
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Support functions. // Support functions.
...@@ -4897,6 +4906,20 @@ void MacroAssembler::AssertString(Register object) { ...@@ -4897,6 +4906,20 @@ void MacroAssembler::AssertString(Register object) {
} }
void MacroAssembler::AssertName(Register object) {
if (emit_debug_code()) {
STATIC_ASSERT(kSmiTag == 0);
And(t0, object, Operand(kSmiTagMask));
Check(ne, "Operand is a smi and not a name", t0, Operand(zero_reg));
push(object);
lw(object, FieldMemOperand(object, HeapObject::kMapOffset));
lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset));
pop(object);
Check(le, "Operand is not a name", object, Operand(LAST_NAME_TYPE));
}
}
void MacroAssembler::AssertRootValue(Register src, void MacroAssembler::AssertRootValue(Register src,
Heap::RootListIndex root_value_index, Heap::RootListIndex root_value_index,
const char* message) { const char* message) {
......
...@@ -900,6 +900,10 @@ class MacroAssembler: public Assembler { ...@@ -900,6 +900,10 @@ class MacroAssembler: public Assembler {
Register scratch, Register scratch,
Label* fail); Label* fail);
void IsObjectNameType(Register object,
Register scratch,
Label* fail);
#ifdef ENABLE_DEBUGGER_SUPPORT #ifdef ENABLE_DEBUGGER_SUPPORT
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Debugger Support. // Debugger Support.
...@@ -1357,6 +1361,9 @@ class MacroAssembler: public Assembler { ...@@ -1357,6 +1361,9 @@ class MacroAssembler: public Assembler {
// Abort execution if argument is not a string, enabled via --debug-code. // Abort execution if argument is not a string, enabled via --debug-code.
void AssertString(Register object); void AssertString(Register object);
// Abort execution if argument is not a name, enabled via --debug-code.
void AssertName(Register object);
// Abort execution if argument is not the root value with the given index, // Abort execution if argument is not the root value with the given index,
// enabled via --debug-code. // enabled via --debug-code.
void AssertRootValue(Register src, void AssertRootValue(Register src,
......
This diff is collapsed.
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