inline HeapObject* ShortCircuitConsString(Object** p) {
- // Optimization: If the heap object pointed to by p is a cons string whose
- // right substring is Heap::empty_string, update it in place to its left
- // substring. Return the updated value.
+ // Optimization: If the heap object pointed to by p is a non-symbol
+ // cons string whose right substring is Heap::empty_string, update
+ // it in place to its left substring. Return the updated value.
//
// Here we assume that if we change *p, we replace it with a heap object
// (ie, the left substring of a cons string is always a heap object).
//
// The check performed is:
- // object->IsConsString() &&
+ // object->IsConsString() && !object->IsSymbol() &&
// (ConsString::cast(object)->second() == Heap::empty_string())
// except the maps for the object and its possible substrings might be
// marked.
MapWord map_word = object->map_word();
map_word.ClearMark();
InstanceType type = map_word.ToMap()->instance_type();
- if (type >= FIRST_NONSTRING_TYPE) return object;
+ if (type >= FIRST_NONSTRING_TYPE || (type & kIsSymbolMask) != 0) {
+ return object;
+ }
StringRepresentationTag rep =
static_cast<StringRepresentationTag>(type & kStringRepresentationMask);
if (value->IsJSFunction()) {
JSFunction* function = JSFunction::cast(value);
- Object* new_map =
- map()->CopyDropTransitions();
+ Object* new_map = map()->CopyDropTransitions();
if (new_map->IsFailure()) return new_map;
set_map(Map::cast(new_map));
int new_size = number_of_descriptors() - transitions - null_descriptors;
// If key is in descriptor, we replace it in-place when filtering.
- int index = Search(descriptor->key());
+ int index = Search(descriptor->GetKey());
const bool inserting = (index == kNotFound);
const bool replacing = !inserting;
bool keep_enumeration_index = false;
// and inserting or replacing a descriptor.
DescriptorWriter w(new_descriptors);
DescriptorReader r(this);
- uint32_t descriptor_hash = descriptor->key()->Hash();
+ uint32_t descriptor_hash = descriptor->GetKey()->Hash();
for (; !r.eos(); r.advance()) {
if (r.GetKey()->Hash() > descriptor_hash ||
uint32_t Hash() { return string_->Hash(); }
Object* GetObject() {
+ // If the string is a cons string, attempt to flatten it so that
+ // symbols will most often be flat strings.
+ if (string_->IsConsString()) {
+ ConsString* cons_string = ConsString::cast(string_);
+ cons_string->TryFlatten();
+ if (cons_string->second() == Heap::empty_string()) {
+ string_ = String::cast(cons_string->first());
+ }
+ }
// Transform string to symbol if possible.
Map* map = Heap::SymbolMapForString(string_);
if (map != NULL) {
Consume(Token::STRING);
Handle<String> symbol =
factory()->LookupSymbol(scanner_.literal_string(),
- scanner_.literal_length());
+ scanner_.literal_length());
result = NEW(Literal(symbol));
break;
}
case Token::STRING: {
Consume(Token::STRING);
Handle<String> string =
- factory()->LookupSymbol(scanner_.literal_string(),
- scanner_.literal_length());
+ factory()->LookupSymbol(scanner_.literal_string(),
+ scanner_.literal_length());
uint32_t index;
if (!string.is_null() && string->AsArrayIndex(&index)) {
key = NewNumberLiteral(index);
Expect(Token::IDENTIFIER, ok);
if (!*ok) return Handle<String>();
return factory()->LookupSymbol(scanner_.literal_string(),
- scanner_.literal_length());
+ scanner_.literal_length());
}
// This function reads an identifier and determines whether or not it
return Smi::cast(value)->value();
}
- String* key() { return key_; }
-
Object* KeyToSymbol() {
if (!key_->IsSymbol()) {
Object* result = Heap::LookupSymbol(key_);