From 6aed5267339480164cfbc844203e4f0b4a58faaf Mon Sep 17 00:00:00 2001 From: "mvstanton@chromium.org" Date: Thu, 27 Jun 2013 13:39:44 +0000 Subject: [PATCH] The check for internalized strings relied on the fact that we had less than 64 distinct InstanceTypes. We are hitting that boundary, so this check needs to be more comprehensive. In fact, two bits need to be tested: verify that kNotStringTag isn't set, and that kInternalizedTag is set. BUG= R=yangguo@chromium.org Review URL: https://codereview.chromium.org/17895002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15358 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 58 +++++++++++++++++----------------------- src/arm/ic-arm.cc | 3 ++- src/arm/macro-assembler-arm.cc | 10 +++++++ src/arm/macro-assembler-arm.h | 1 + src/ia32/code-stubs-ia32.cc | 46 +++++++++++-------------------- src/ia32/ic-ia32.cc | 3 ++- src/ia32/macro-assembler-ia32.cc | 11 ++++++++ src/ia32/macro-assembler-ia32.h | 9 +++++++ src/objects-inl.h | 21 +++++++-------- src/objects.h | 3 +-- src/x64/code-stubs-x64.cc | 54 +++++++++++++------------------------ src/x64/ic-x64.cc | 3 ++- src/x64/macro-assembler-x64.cc | 26 ++++++++++++++++++ src/x64/macro-assembler-x64.h | 6 +++++ 14 files changed, 136 insertions(+), 118 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 1d1fe83..9cdaa12 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -892,12 +892,17 @@ static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, // Now that we have the types we might as well check for // internalized-internalized. - // Ensure that no non-strings have the internalized bit set. - STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsInternalizedMask); + Label not_internalized; STATIC_ASSERT(kInternalizedTag != 0); - __ and_(r2, r2, Operand(r3)); - __ tst(r2, Operand(kIsInternalizedMask)); - __ b(ne, &return_not_equal); + __ and_(r2, r2, Operand(kIsNotStringMask | kIsInternalizedMask)); + __ cmp(r2, Operand(kInternalizedTag | kStringTag)); + __ b(ne, ¬_internalized); // r2 (rhs) is not an internalized string + + __ and_(r3, r3, Operand(kIsNotStringMask | kIsInternalizedMask)); + __ cmp(r3, Operand(kInternalizedTag | kStringTag)); + __ b(eq, &return_not_equal); // both rhs and lhs are internalized strings + + __ bind(¬_internalized); } @@ -937,7 +942,6 @@ static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm, (lhs.is(r1) && rhs.is(r0))); // r2 is object type of rhs. - // Ensure that no non-strings have the internalized bit set. Label object_test; STATIC_ASSERT(kInternalizedTag != 0); __ tst(r2, Operand(kIsNotStringMask)); @@ -6213,9 +6217,14 @@ void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset)); __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset)); STATIC_ASSERT(kInternalizedTag != 0); - __ and_(tmp1, tmp1, Operand(tmp2)); - __ tst(tmp1, Operand(kIsInternalizedMask)); - __ b(eq, &miss); + + __ and_(tmp1, tmp1, Operand(kIsNotStringMask | kIsInternalizedMask)); + __ cmp(tmp1, Operand(kInternalizedTag | kStringTag)); + __ b(ne, &miss); + + __ and_(tmp2, tmp2, Operand(kIsNotStringMask | kIsInternalizedMask)); + __ cmp(tmp2, Operand(kInternalizedTag | kStringTag)); + __ b(ne, &miss); // Internalized strings are compared by identity. __ cmp(left, right); @@ -6254,19 +6263,8 @@ void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset)); __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset)); - Label succeed1; - __ tst(tmp1, Operand(kIsInternalizedMask)); - __ b(ne, &succeed1); - __ cmp(tmp1, Operand(SYMBOL_TYPE)); - __ b(ne, &miss); - __ bind(&succeed1); - - Label succeed2; - __ tst(tmp2, Operand(kIsInternalizedMask)); - __ b(ne, &succeed2); - __ cmp(tmp2, Operand(SYMBOL_TYPE)); - __ b(ne, &miss); - __ bind(&succeed2); + __ JumpIfNotUniqueName(tmp1, &miss); + __ JumpIfNotUniqueName(tmp2, &miss); // Unique names are compared by identity. __ cmp(left, right); @@ -6321,7 +6319,8 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { // Handle not identical strings. // Check that both strings are internalized strings. If they are, we're done - // because we already know they are not identical. + // because we already know they are not identical. We know they are both + // strings. if (equality) { ASSERT(GetCondition() == eq); STATIC_ASSERT(kInternalizedTag != 0); @@ -6507,11 +6506,7 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); __ ldrb(entity_name, FieldMemOperand(entity_name, Map::kInstanceTypeOffset)); - __ tst(entity_name, Operand(kIsInternalizedMask)); - __ b(ne, &good); - __ cmp(entity_name, Operand(SYMBOL_TYPE)); - __ b(ne, miss); - + __ JumpIfNotUniqueName(entity_name, miss); __ bind(&good); // Restore the properties. @@ -6678,15 +6673,10 @@ void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { // Check if the entry name is not a unique name. - Label cont; __ ldr(entry_key, FieldMemOperand(entry_key, HeapObject::kMapOffset)); __ ldrb(entry_key, FieldMemOperand(entry_key, Map::kInstanceTypeOffset)); - __ tst(entry_key, Operand(kIsInternalizedMask)); - __ b(ne, &cont); - __ cmp(entry_key, Operand(SYMBOL_TYPE)); - __ b(ne, &maybe_in_dictionary); - __ bind(&cont); + __ JumpIfNotUniqueName(entry_key, &maybe_in_dictionary); } } diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc index 3d421c1..cc78151 100644 --- a/src/arm/ic-arm.cc +++ b/src/arm/ic-arm.cc @@ -321,7 +321,8 @@ static void GenerateKeyNameCheck(MacroAssembler* masm, __ tst(hash, Operand(Name::kContainsCachedArrayIndexMask)); __ b(eq, index_string); - // Is the string internalized? + // Is the string internalized? We know it's a string, so a single + // bit test is enough. // map: key map __ ldrb(hash, FieldMemOperand(map, Map::kInstanceTypeOffset)); STATIC_ASSERT(kInternalizedTag != 0); diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc index 81a2d37..fb379e2 100644 --- a/src/arm/macro-assembler-arm.cc +++ b/src/arm/macro-assembler-arm.cc @@ -3089,6 +3089,16 @@ void MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register first, } +void MacroAssembler::JumpIfNotUniqueName(Register reg, + Label* not_unique_name) { + STATIC_ASSERT(((SYMBOL_TYPE - 1) & kIsInternalizedMask) == kInternalizedTag); + cmp(reg, Operand(kInternalizedTag)); + b(lt, not_unique_name); + cmp(reg, Operand(SYMBOL_TYPE)); + b(gt, not_unique_name); +} + + // Allocates a heap number or jumps to the need_gc label if the young space // is full and a scavenge is needed. void MacroAssembler::AllocateHeapNumber(Register result, diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h index 8d3626d..b76ebd5 100644 --- a/src/arm/macro-assembler-arm.h +++ b/src/arm/macro-assembler-arm.h @@ -1296,6 +1296,7 @@ class MacroAssembler: public Assembler { Register scratch, Label* failure); + void JumpIfNotUniqueName(Register reg, Label* not_unique_name); // --------------------------------------------------------------------------- // Patching helpers. diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 0ca5698..83b753b 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -6853,9 +6853,13 @@ void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { __ movzx_b(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); __ movzx_b(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); STATIC_ASSERT(kInternalizedTag != 0); - __ and_(tmp1, tmp2); - __ test(tmp1, Immediate(kIsInternalizedMask)); - __ j(zero, &miss, Label::kNear); + __ and_(tmp1, Immediate(kIsNotStringMask | kIsInternalizedMask)); + __ cmpb(tmp1, kInternalizedTag | kStringTag); + __ j(not_equal, &miss, Label::kNear); + + __ and_(tmp2, Immediate(kIsNotStringMask | kIsInternalizedMask)); + __ cmpb(tmp2, kInternalizedTag | kStringTag); + __ j(not_equal, &miss, Label::kNear); // Internalized strings are compared by identity. Label done; @@ -6900,19 +6904,8 @@ void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { __ movzx_b(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); __ movzx_b(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); - Label succeed1; - __ test(tmp1, Immediate(kIsInternalizedMask)); - __ j(not_zero, &succeed1); - __ cmpb(tmp1, static_cast(SYMBOL_TYPE)); - __ j(not_equal, &miss); - __ bind(&succeed1); - - Label succeed2; - __ test(tmp2, Immediate(kIsInternalizedMask)); - __ j(not_zero, &succeed2); - __ cmpb(tmp2, static_cast(SYMBOL_TYPE)); - __ j(not_equal, &miss); - __ bind(&succeed2); + __ JumpIfNotUniqueName(tmp1, &miss, Label::kNear); + __ JumpIfNotUniqueName(tmp2, &miss, Label::kNear); // Unique names are compared by identity. Label done; @@ -6977,7 +6970,8 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { // Check that both strings are internalized. If they are, we're done // because we already know they are not identical. But in the case of - // non-equality compare, we still need to determine the order. + // non-equality compare, we still need to determine the order. We + // also know they are both strings. if (equality) { Label do_compare; STATIC_ASSERT(kInternalizedTag != 0); @@ -7136,12 +7130,8 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, // Check if the entry name is not a unique name. __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); - __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset), - kIsInternalizedMask); - __ j(not_zero, &good); - __ cmpb(FieldOperand(entity_name, Map::kInstanceTypeOffset), - static_cast(SYMBOL_TYPE)); - __ j(not_equal, miss); + __ JumpIfNotUniqueName(FieldOperand(entity_name, Map::kInstanceTypeOffset), + miss); __ bind(&good); } @@ -7274,15 +7264,9 @@ void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { // key we are looking for. // Check if the entry name is not a unique name. - Label cont; __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); - __ test_b(FieldOperand(scratch, Map::kInstanceTypeOffset), - kIsInternalizedMask); - __ j(not_zero, &cont); - __ cmpb(FieldOperand(scratch, Map::kInstanceTypeOffset), - static_cast(SYMBOL_TYPE)); - __ j(not_equal, &maybe_in_dictionary); - __ bind(&cont); + __ JumpIfNotUniqueName(FieldOperand(scratch, Map::kInstanceTypeOffset), + &maybe_in_dictionary); } } diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc index 2e27097..10d6c86 100644 --- a/src/ia32/ic-ia32.cc +++ b/src/ia32/ic-ia32.cc @@ -317,7 +317,8 @@ static void GenerateKeyNameCheck(MacroAssembler* masm, __ test(hash, Immediate(Name::kContainsCachedArrayIndexMask)); __ j(zero, index_string); - // Is the string internalized? + // Is the string internalized? We already know it's a string so a single + // bit test is enough. STATIC_ASSERT(kInternalizedTag != 0); __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), kIsInternalizedMask); __ j(zero, not_unique); diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc index 17d4aac..31e9e53 100644 --- a/src/ia32/macro-assembler-ia32.cc +++ b/src/ia32/macro-assembler-ia32.cc @@ -2807,6 +2807,17 @@ void MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register object1, } +void MacroAssembler::JumpIfNotUniqueName(Operand operand, + Label* not_unique_name, + Label::Distance distance) { + STATIC_ASSERT(((SYMBOL_TYPE - 1) & kIsInternalizedMask) == kInternalizedTag); + cmp(operand, Immediate(kInternalizedTag)); + j(less, not_unique_name, distance); + cmp(operand, Immediate(SYMBOL_TYPE)); + j(greater, not_unique_name, distance); +} + + void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) { int frame_alignment = OS::ActivationFrameAlignment(); if (frame_alignment != 0) { diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h index 7d780f0..5cb8286 100644 --- a/src/ia32/macro-assembler-ia32.h +++ b/src/ia32/macro-assembler-ia32.h @@ -884,6 +884,15 @@ class MacroAssembler: public Assembler { Register scratch2, Label* on_not_flat_ascii_strings); + // Checks if the given register or operand is a unique name + void JumpIfNotUniqueName(Register reg, Label* not_unique_name, + Label::Distance distance = Label::kFar) { + JumpIfNotUniqueName(Operand(reg), not_unique_name, distance); + } + + void JumpIfNotUniqueName(Operand operand, Label* not_unique_name, + Label::Distance distance = Label::kFar); + static int SafepointRegisterStackIndex(Register reg) { return SafepointRegisterStackIndex(reg.code()); } diff --git a/src/objects-inl.h b/src/objects-inl.h index ff0e865..ea347fd 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -221,12 +221,9 @@ bool Object::IsSpecFunction() { bool Object::IsInternalizedString() { if (!this->IsHeapObject()) return false; uint32_t type = HeapObject::cast(this)->map()->instance_type(); - // Because the internalized tag is non-zero and no non-string types have the - // internalized bit set we can test for internalized strings with a very - // simple test operation. STATIC_ASSERT(kInternalizedTag != 0); - ASSERT(kNotStringTag + kIsInternalizedMask > LAST_TYPE); - return (type & kIsInternalizedMask) != 0; + return (type & (kIsNotStringMask | kIsInternalizedMask)) == + (kInternalizedTag | kStringTag); } @@ -323,7 +320,8 @@ StringShape::StringShape(InstanceType t) bool StringShape::IsInternalized() { ASSERT(valid()); STATIC_ASSERT(kInternalizedTag != 0); - return (type_ & kIsInternalizedMask) != 0; + return (type_ & (kIsNotStringMask | kIsInternalizedMask)) == + (kInternalizedTag | kStringTag); } @@ -3389,15 +3387,13 @@ int Map::pre_allocated_property_fields() { int HeapObject::SizeFromMap(Map* map) { int instance_size = map->instance_size(); if (instance_size != kVariableSizeSentinel) return instance_size; - // We can ignore the "internalized" bit because it is only set for strings - // and thus implies a string type. - int instance_type = - static_cast(map->instance_type()) & ~kIsInternalizedMask; // Only inline the most frequent cases. + int instance_type = static_cast(map->instance_type()); if (instance_type == FIXED_ARRAY_TYPE) { return FixedArray::BodyDescriptor::SizeOf(map, this); } - if (instance_type == ASCII_STRING_TYPE) { + if (instance_type == ASCII_STRING_TYPE || + instance_type == ASCII_INTERNALIZED_STRING_TYPE) { return SeqOneByteString::SizeFor( reinterpret_cast(this)->length()); } @@ -3407,7 +3403,8 @@ int HeapObject::SizeFromMap(Map* map) { if (instance_type == FREE_SPACE_TYPE) { return reinterpret_cast(this)->size(); } - if (instance_type == STRING_TYPE) { + if (instance_type == STRING_TYPE || + instance_type == INTERNALIZED_STRING_TYPE) { return SeqTwoByteString::SizeFor( reinterpret_cast(this)->length()); } diff --git a/src/objects.h b/src/objects.h index 01c3157..adaa9cf 100644 --- a/src/objects.h +++ b/src/objects.h @@ -575,8 +575,7 @@ const uint32_t kStringTag = 0x0; const uint32_t kNotStringTag = 0x80; // Bit 6 indicates that the object is an internalized string (if set) or not. -// There are not enough types that the non-string types (with bit 7 set) can -// have bit 6 set too. +// Bit 7 has to be clear as well. const uint32_t kIsInternalizedMask = 0x40; const uint32_t kNotInternalizedTag = 0x0; const uint32_t kInternalizedTag = 0x40; diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index ab3064f..897f008 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -3436,11 +3436,10 @@ static void BranchIfNotInternalizedString(MacroAssembler* masm, __ movq(scratch, FieldOperand(object, HeapObject::kMapOffset)); __ movzxbq(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); - // Ensure that no non-strings have the internalized bit set. - STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsInternalizedMask); STATIC_ASSERT(kInternalizedTag != 0); - __ testb(scratch, Immediate(kIsInternalizedMask)); - __ j(zero, label); + __ and_(scratch, Immediate(kIsNotStringMask | kIsInternalizedMask)); + __ cmpb(scratch, Immediate(kInternalizedTag | kStringTag)); + __ j(not_equal, label); } @@ -5845,9 +5844,13 @@ void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { __ movzxbq(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); __ movzxbq(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); STATIC_ASSERT(kInternalizedTag != 0); - __ and_(tmp1, tmp2); - __ testb(tmp1, Immediate(kIsInternalizedMask)); - __ j(zero, &miss, Label::kNear); + __ and_(tmp1, Immediate(kIsNotStringMask | kIsInternalizedMask)); + __ cmpb(tmp1, Immediate(kInternalizedTag | kStringTag)); + __ j(not_equal, &miss, Label::kNear); + + __ and_(tmp2, Immediate(kIsNotStringMask | kIsInternalizedMask)); + __ cmpb(tmp2, Immediate(kInternalizedTag | kStringTag)); + __ j(not_equal, &miss, Label::kNear); // Internalized strings are compared by identity. Label done; @@ -5890,19 +5893,8 @@ void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { __ movzxbq(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); __ movzxbq(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); - Label succeed1; - __ testb(tmp1, Immediate(kIsInternalizedMask)); - __ j(not_zero, &succeed1, Label::kNear); - __ cmpb(tmp1, Immediate(static_cast(SYMBOL_TYPE))); - __ j(not_equal, &miss, Label::kNear); - __ bind(&succeed1); - - Label succeed2; - __ testb(tmp2, Immediate(kIsInternalizedMask)); - __ j(not_zero, &succeed2, Label::kNear); - __ cmpb(tmp2, Immediate(static_cast(SYMBOL_TYPE))); - __ j(not_equal, &miss, Label::kNear); - __ bind(&succeed2); + __ JumpIfNotUniqueName(tmp1, &miss, Label::kNear); + __ JumpIfNotUniqueName(tmp2, &miss, Label::kNear); // Unique names are compared by identity. Label done; @@ -5964,7 +5956,8 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { __ bind(¬_same); // Check that both strings are internalized strings. If they are, we're done - // because we already know they are not identical. + // because we already know they are not identical. We also know they are both + // strings. if (equality) { Label do_compare; STATIC_ASSERT(kInternalizedTag != 0); @@ -6120,13 +6113,8 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, // Check if the entry name is not a unique name. __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); - __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), - Immediate(kIsInternalizedMask)); - __ j(not_zero, &good, Label::kNear); - __ cmpb(FieldOperand(entity_name, Map::kInstanceTypeOffset), - Immediate(static_cast(SYMBOL_TYPE))); - __ j(not_equal, miss); - + __ JumpIfNotUniqueName(FieldOperand(entity_name, Map::kInstanceTypeOffset), + miss); __ bind(&good); } @@ -6252,15 +6240,9 @@ void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { // key we are looking for. // Check if the entry name is not a unique name. - Label cont; __ movq(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); - __ testb(FieldOperand(scratch, Map::kInstanceTypeOffset), - Immediate(kIsInternalizedMask)); - __ j(not_zero, &cont); - __ cmpb(FieldOperand(scratch, Map::kInstanceTypeOffset), - Immediate(static_cast(SYMBOL_TYPE))); - __ j(not_equal, &maybe_in_dictionary); - __ bind(&cont); + __ JumpIfNotUniqueName(FieldOperand(scratch, Map::kInstanceTypeOffset), + &maybe_in_dictionary); } } diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc index ce91eff..82112a0 100644 --- a/src/x64/ic-x64.cc +++ b/src/x64/ic-x64.cc @@ -337,7 +337,8 @@ static void GenerateKeyNameCheck(MacroAssembler* masm, __ testl(hash, Immediate(Name::kContainsCachedArrayIndexMask)); __ j(zero, index_string); // The value in hash is used at jump target. - // Is the string internalized? + // Is the string internalized? We already know it's a string so a single + // bit test is enough. STATIC_ASSERT(kInternalizedTag != 0); __ testb(FieldOperand(map, Map::kInstanceTypeOffset), Immediate(kIsInternalizedMask)); diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index 5575985..a4d64b9 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -2308,6 +2308,32 @@ void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialAscii( } +template +static void JumpIfNotUniqueNameHelper(MacroAssembler* masm, + T operand_or_register, + Label* not_unique_name, + Label::Distance distance) { + STATIC_ASSERT(((SYMBOL_TYPE - 1) & kIsInternalizedMask) == kInternalizedTag); + masm->cmpb(operand_or_register, Immediate(kInternalizedTag)); + masm->j(less, not_unique_name, distance); + masm->cmpb(operand_or_register, Immediate(SYMBOL_TYPE)); + masm->j(greater, not_unique_name, distance); +} + + +void MacroAssembler::JumpIfNotUniqueName(Operand operand, + Label* not_unique_name, + Label::Distance distance) { + JumpIfNotUniqueNameHelper(this, operand, not_unique_name, distance); +} + + +void MacroAssembler::JumpIfNotUniqueName(Register reg, + Label* not_unique_name, + Label::Distance distance) { + JumpIfNotUniqueNameHelper(this, reg, not_unique_name, distance); +} + void MacroAssembler::Move(Register dst, Register src) { if (!dst.is(src)) { diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h index 1b7e586..14228cc 100644 --- a/src/x64/macro-assembler-x64.h +++ b/src/x64/macro-assembler-x64.h @@ -758,6 +758,12 @@ class MacroAssembler: public Assembler { Label* on_fail, Label::Distance near_jump = Label::kFar); + // Checks if the given register or operand is a unique name + void JumpIfNotUniqueName(Register reg, Label* not_unique_name, + Label::Distance distance = Label::kFar); + void JumpIfNotUniqueName(Operand operand, Label* not_unique_name, + Label::Distance distance = Label::kFar); + // --------------------------------------------------------------------------- // Macro instructions. -- 2.7.4