| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 952 resource->data(), | 952 resource->data(), |
| 953 resource->length() * sizeof(smart_chars[0])) == 0); | 953 resource->length() * sizeof(smart_chars[0])) == 0); |
| 954 } | 954 } |
| 955 #endif // DEBUG | 955 #endif // DEBUG |
| 956 Heap* heap = GetHeap(); | 956 Heap* heap = GetHeap(); |
| 957 int size = this->Size(); // Byte size of the original string. | 957 int size = this->Size(); // Byte size of the original string. |
| 958 if (size < ExternalString::kShortSize) { | 958 if (size < ExternalString::kShortSize) { |
| 959 return false; | 959 return false; |
| 960 } | 960 } |
| 961 bool is_ascii = this->IsOneByteRepresentation(); | 961 bool is_ascii = this->IsOneByteRepresentation(); |
| 962 bool is_symbol = this->IsSymbol(); | 962 bool is_internalized = this->IsInternalizedString(); |
| 963 | 963 |
| 964 // Morph the object to an external string by adjusting the map and | 964 // Morph the object to an external string by adjusting the map and |
| 965 // reinitializing the fields. | 965 // reinitializing the fields. |
| 966 if (size >= ExternalString::kSize) { | 966 if (size >= ExternalString::kSize) { |
| 967 this->set_map_no_write_barrier( | 967 this->set_map_no_write_barrier( |
| 968 is_symbol | 968 is_internalized |
| 969 ? (is_ascii ? heap->external_symbol_with_ascii_data_map() | 969 ? (is_ascii |
| 970 : heap->external_symbol_map()) | 970 ? heap->external_internalized_string_with_ascii_data_map() |
| 971 : (is_ascii ? heap->external_string_with_ascii_data_map() | 971 : heap->external_internalized_string_map()) |
| 972 : heap->external_string_map())); | 972 : (is_ascii |
| 973 ? heap->external_string_with_ascii_data_map() |
| 974 : heap->external_string_map())); |
| 973 } else { | 975 } else { |
| 974 this->set_map_no_write_barrier( | 976 this->set_map_no_write_barrier( |
| 975 is_symbol | 977 is_internalized |
| 976 ? (is_ascii ? heap->short_external_symbol_with_ascii_data_map() | 978 ? (is_ascii |
| 977 : heap->short_external_symbol_map()) | 979 ? heap-> |
| 978 : (is_ascii ? heap->short_external_string_with_ascii_data_map() | 980 short_external_internalized_string_with_ascii_data_map() |
| 979 : heap->short_external_string_map())); | 981 : heap->short_external_internalized_string_map()) |
| 982 : (is_ascii |
| 983 ? heap->short_external_string_with_ascii_data_map() |
| 984 : heap->short_external_string_map())); |
| 980 } | 985 } |
| 981 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); | 986 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); |
| 982 self->set_resource(resource); | 987 self->set_resource(resource); |
| 983 if (is_symbol) self->Hash(); // Force regeneration of the hash value. | 988 if (is_internalized) self->Hash(); // Force regeneration of the hash value. |
| 984 | 989 |
| 985 // Fill the remainder of the string with dead wood. | 990 // Fill the remainder of the string with dead wood. |
| 986 int new_size = this->Size(); // Byte size of the external String object. | 991 int new_size = this->Size(); // Byte size of the external String object. |
| 987 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); | 992 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
| 988 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { | 993 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { |
| 989 MemoryChunk::IncrementLiveBytesFromMutator(this->address(), | 994 MemoryChunk::IncrementLiveBytesFromMutator(this->address(), |
| 990 new_size - size); | 995 new_size - size); |
| 991 } | 996 } |
| 992 return true; | 997 return true; |
| 993 } | 998 } |
| 994 | 999 |
| 995 | 1000 |
| 996 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { | 1001 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { |
| 997 #ifdef DEBUG | 1002 #ifdef DEBUG |
| 998 if (FLAG_enable_slow_asserts) { | 1003 if (FLAG_enable_slow_asserts) { |
| 999 // Assert that the resource and the string are equivalent. | 1004 // Assert that the resource and the string are equivalent. |
| 1000 ASSERT(static_cast<size_t>(this->length()) == resource->length()); | 1005 ASSERT(static_cast<size_t>(this->length()) == resource->length()); |
| 1001 ScopedVector<char> smart_chars(this->length()); | 1006 ScopedVector<char> smart_chars(this->length()); |
| 1002 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); | 1007 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); |
| 1003 ASSERT(memcmp(smart_chars.start(), | 1008 ASSERT(memcmp(smart_chars.start(), |
| 1004 resource->data(), | 1009 resource->data(), |
| 1005 resource->length() * sizeof(smart_chars[0])) == 0); | 1010 resource->length() * sizeof(smart_chars[0])) == 0); |
| 1006 } | 1011 } |
| 1007 #endif // DEBUG | 1012 #endif // DEBUG |
| 1008 Heap* heap = GetHeap(); | 1013 Heap* heap = GetHeap(); |
| 1009 int size = this->Size(); // Byte size of the original string. | 1014 int size = this->Size(); // Byte size of the original string. |
| 1010 if (size < ExternalString::kShortSize) { | 1015 if (size < ExternalString::kShortSize) { |
| 1011 return false; | 1016 return false; |
| 1012 } | 1017 } |
| 1013 bool is_symbol = this->IsSymbol(); | 1018 bool is_internalized = this->IsInternalizedString(); |
| 1014 | 1019 |
| 1015 // Morph the object to an external string by adjusting the map and | 1020 // Morph the object to an external string by adjusting the map and |
| 1016 // reinitializing the fields. Use short version if space is limited. | 1021 // reinitializing the fields. Use short version if space is limited. |
| 1017 if (size >= ExternalString::kSize) { | 1022 if (size >= ExternalString::kSize) { |
| 1018 this->set_map_no_write_barrier( | 1023 this->set_map_no_write_barrier( |
| 1019 is_symbol ? heap->external_ascii_symbol_map() | 1024 is_internalized ? heap->external_ascii_internalized_string_map() |
| 1020 : heap->external_ascii_string_map()); | 1025 : heap->external_ascii_string_map()); |
| 1021 } else { | 1026 } else { |
| 1022 this->set_map_no_write_barrier( | 1027 this->set_map_no_write_barrier( |
| 1023 is_symbol ? heap->short_external_ascii_symbol_map() | 1028 is_internalized ? heap->short_external_ascii_internalized_string_map() |
| 1024 : heap->short_external_ascii_string_map()); | 1029 : heap->short_external_ascii_string_map()); |
| 1025 } | 1030 } |
| 1026 ExternalAsciiString* self = ExternalAsciiString::cast(this); | 1031 ExternalAsciiString* self = ExternalAsciiString::cast(this); |
| 1027 self->set_resource(resource); | 1032 self->set_resource(resource); |
| 1028 if (is_symbol) self->Hash(); // Force regeneration of the hash value. | 1033 if (is_internalized) self->Hash(); // Force regeneration of the hash value. |
| 1029 | 1034 |
| 1030 // Fill the remainder of the string with dead wood. | 1035 // Fill the remainder of the string with dead wood. |
| 1031 int new_size = this->Size(); // Byte size of the external String object. | 1036 int new_size = this->Size(); // Byte size of the external String object. |
| 1032 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); | 1037 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
| 1033 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { | 1038 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { |
| 1034 MemoryChunk::IncrementLiveBytesFromMutator(this->address(), | 1039 MemoryChunk::IncrementLiveBytesFromMutator(this->address(), |
| 1035 new_size - size); | 1040 new_size - size); |
| 1036 } | 1041 } |
| 1037 return true; | 1042 return true; |
| 1038 } | 1043 } |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1488 // print that using vsnprintf (which may truncate but never allocate if | 1493 // print that using vsnprintf (which may truncate but never allocate if |
| 1489 // there is no more space in the buffer). | 1494 // there is no more space in the buffer). |
| 1490 EmbeddedVector<char, 100> buffer; | 1495 EmbeddedVector<char, 100> buffer; |
| 1491 OS::SNPrintF(buffer, "%.16g", Number()); | 1496 OS::SNPrintF(buffer, "%.16g", Number()); |
| 1492 accumulator->Add("%s", buffer.start()); | 1497 accumulator->Add("%s", buffer.start()); |
| 1493 } | 1498 } |
| 1494 | 1499 |
| 1495 | 1500 |
| 1496 String* JSReceiver::class_name() { | 1501 String* JSReceiver::class_name() { |
| 1497 if (IsJSFunction() && IsJSFunctionProxy()) { | 1502 if (IsJSFunction() && IsJSFunctionProxy()) { |
| 1498 return GetHeap()->function_class_symbol(); | 1503 return GetHeap()->function_class_string(); |
| 1499 } | 1504 } |
| 1500 if (map()->constructor()->IsJSFunction()) { | 1505 if (map()->constructor()->IsJSFunction()) { |
| 1501 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1506 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
| 1502 return String::cast(constructor->shared()->instance_class_name()); | 1507 return String::cast(constructor->shared()->instance_class_name()); |
| 1503 } | 1508 } |
| 1504 // If the constructor is not present, return "Object". | 1509 // If the constructor is not present, return "Object". |
| 1505 return GetHeap()->Object_symbol(); | 1510 return GetHeap()->Object_string(); |
| 1506 } | 1511 } |
| 1507 | 1512 |
| 1508 | 1513 |
| 1509 String* JSReceiver::constructor_name() { | 1514 String* JSReceiver::constructor_name() { |
| 1510 if (map()->constructor()->IsJSFunction()) { | 1515 if (map()->constructor()->IsJSFunction()) { |
| 1511 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1516 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
| 1512 String* name = String::cast(constructor->shared()->name()); | 1517 String* name = String::cast(constructor->shared()->name()); |
| 1513 if (name->length() > 0) return name; | 1518 if (name->length() > 0) return name; |
| 1514 String* inferred_name = constructor->shared()->inferred_name(); | 1519 String* inferred_name = constructor->shared()->inferred_name(); |
| 1515 if (inferred_name->length() > 0) return inferred_name; | 1520 if (inferred_name->length() > 0) return inferred_name; |
| 1516 Object* proto = GetPrototype(); | 1521 Object* proto = GetPrototype(); |
| 1517 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); | 1522 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); |
| 1518 } | 1523 } |
| 1519 // TODO(rossberg): what about proxies? | 1524 // TODO(rossberg): what about proxies? |
| 1520 // If the constructor is not present, return "Object". | 1525 // If the constructor is not present, return "Object". |
| 1521 return GetHeap()->Object_symbol(); | 1526 return GetHeap()->Object_string(); |
| 1522 } | 1527 } |
| 1523 | 1528 |
| 1524 | 1529 |
| 1525 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, | 1530 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, |
| 1526 String* name, | 1531 String* name, |
| 1527 Object* value, | 1532 Object* value, |
| 1528 int field_index) { | 1533 int field_index) { |
| 1529 if (map()->unused_property_fields() == 0) { | 1534 if (map()->unused_property_fields() == 0) { |
| 1530 int new_unused = new_map->unused_property_fields(); | 1535 int new_unused = new_map->unused_property_fields(); |
| 1531 FixedArray* values; | 1536 FixedArray* values; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1560 MaybeObject* JSObject::AddFastProperty(String* name, | 1565 MaybeObject* JSObject::AddFastProperty(String* name, |
| 1561 Object* value, | 1566 Object* value, |
| 1562 PropertyAttributes attributes, | 1567 PropertyAttributes attributes, |
| 1563 StoreFromKeyed store_mode) { | 1568 StoreFromKeyed store_mode) { |
| 1564 ASSERT(!IsJSGlobalProxy()); | 1569 ASSERT(!IsJSGlobalProxy()); |
| 1565 ASSERT(DescriptorArray::kNotFound == | 1570 ASSERT(DescriptorArray::kNotFound == |
| 1566 map()->instance_descriptors()->Search( | 1571 map()->instance_descriptors()->Search( |
| 1567 name, map()->NumberOfOwnDescriptors())); | 1572 name, map()->NumberOfOwnDescriptors())); |
| 1568 | 1573 |
| 1569 // Normalize the object if the name is an actual string (not the | 1574 // Normalize the object if the name is an actual string (not the |
| 1570 // hidden symbols) and is not a real identifier. | 1575 // hidden strings) and is not a real identifier. |
| 1571 // Normalize the object if it will have too many fast properties. | 1576 // Normalize the object if it will have too many fast properties. |
| 1572 Isolate* isolate = GetHeap()->isolate(); | 1577 Isolate* isolate = GetHeap()->isolate(); |
| 1573 if ((!IsIdentifier(isolate->unicode_cache(), name) | 1578 if ((!IsIdentifier(isolate->unicode_cache(), name) |
| 1574 && name != isolate->heap()->hidden_symbol()) || | 1579 && name != isolate->heap()->hidden_string()) || |
| 1575 (map()->unused_property_fields() == 0 && | 1580 (map()->unused_property_fields() == 0 && |
| 1576 TooManyFastProperties(properties()->length(), store_mode))) { | 1581 TooManyFastProperties(properties()->length(), store_mode))) { |
| 1577 Object* obj; | 1582 Object* obj; |
| 1578 MaybeObject* maybe_obj = | 1583 MaybeObject* maybe_obj = |
| 1579 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1584 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 1580 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1585 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1581 | 1586 |
| 1582 return AddSlowProperty(name, value, attributes); | 1587 return AddSlowProperty(name, value, attributes); |
| 1583 } | 1588 } |
| 1584 | 1589 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1742 return *hresult; | 1747 return *hresult; |
| 1743 } | 1748 } |
| 1744 | 1749 |
| 1745 | 1750 |
| 1746 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, | 1751 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, |
| 1747 const char* type_str, | 1752 const char* type_str, |
| 1748 Handle<String> name, | 1753 Handle<String> name, |
| 1749 Handle<Object> old_value) { | 1754 Handle<Object> old_value) { |
| 1750 Isolate* isolate = object->GetIsolate(); | 1755 Isolate* isolate = object->GetIsolate(); |
| 1751 HandleScope scope; | 1756 HandleScope scope; |
| 1752 Handle<String> type = isolate->factory()->LookupUtf8Symbol(type_str); | 1757 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); |
| 1753 if (object->IsJSGlobalObject()) { | 1758 if (object->IsJSGlobalObject()) { |
| 1754 object = handle(JSGlobalObject::cast(*object)->global_receiver(), isolate); | 1759 object = handle(JSGlobalObject::cast(*object)->global_receiver(), isolate); |
| 1755 } | 1760 } |
| 1756 Handle<Object> args[] = { type, object, name, old_value }; | 1761 Handle<Object> args[] = { type, object, name, old_value }; |
| 1757 bool threw; | 1762 bool threw; |
| 1758 Execution::Call(Handle<JSFunction>(isolate->observers_notify_change()), | 1763 Execution::Call(Handle<JSFunction>(isolate->observers_notify_change()), |
| 1759 Handle<Object>(isolate->heap()->undefined_value()), | 1764 Handle<Object>(isolate->heap()->undefined_value()), |
| 1760 old_value->IsTheHole() ? 3 : 4, args, | 1765 old_value->IsTheHole() ? 3 : 4, args, |
| 1761 &threw); | 1766 &threw); |
| 1762 ASSERT(!threw); | 1767 ASSERT(!threw); |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2248 | 2253 |
| 2249 void Map::AppendCallbackDescriptors(Handle<Map> map, | 2254 void Map::AppendCallbackDescriptors(Handle<Map> map, |
| 2250 Handle<Object> descriptors) { | 2255 Handle<Object> descriptors) { |
| 2251 Isolate* isolate = map->GetIsolate(); | 2256 Isolate* isolate = map->GetIsolate(); |
| 2252 Handle<DescriptorArray> array(map->instance_descriptors()); | 2257 Handle<DescriptorArray> array(map->instance_descriptors()); |
| 2253 NeanderArray callbacks(descriptors); | 2258 NeanderArray callbacks(descriptors); |
| 2254 int nof_callbacks = callbacks.length(); | 2259 int nof_callbacks = callbacks.length(); |
| 2255 | 2260 |
| 2256 ASSERT(array->NumberOfSlackDescriptors() >= nof_callbacks); | 2261 ASSERT(array->NumberOfSlackDescriptors() >= nof_callbacks); |
| 2257 | 2262 |
| 2258 // Ensure the keys are symbols before writing them into the instance | 2263 // Ensure the keys are internalized strings before writing them into the |
| 2259 // descriptor. Since it may cause a GC, it has to be done before we | 2264 // instance descriptor. Since it may cause a GC, it has to be done before we |
| 2260 // temporarily put the heap in an invalid state while appending descriptors. | 2265 // temporarily put the heap in an invalid state while appending descriptors. |
| 2261 for (int i = 0; i < nof_callbacks; ++i) { | 2266 for (int i = 0; i < nof_callbacks; ++i) { |
| 2262 Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks.get(i))); | 2267 Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks.get(i))); |
| 2263 Handle<String> key = | 2268 Handle<String> key = |
| 2264 isolate->factory()->SymbolFromString( | 2269 isolate->factory()->InternalizedStringFromString( |
| 2265 Handle<String>(String::cast(entry->name()))); | 2270 Handle<String>(String::cast(entry->name()))); |
| 2266 entry->set_name(*key); | 2271 entry->set_name(*key); |
| 2267 } | 2272 } |
| 2268 | 2273 |
| 2269 int nof = map->NumberOfOwnDescriptors(); | 2274 int nof = map->NumberOfOwnDescriptors(); |
| 2270 | 2275 |
| 2271 // Fill in new callback descriptors. Process the callbacks from | 2276 // Fill in new callback descriptors. Process the callbacks from |
| 2272 // back to front so that the last callback with a given name takes | 2277 // back to front so that the last callback with a given name takes |
| 2273 // precedence over previously added callbacks with that name. | 2278 // precedence over previously added callbacks with that name. |
| 2274 for (int i = nof_callbacks - 1; i >= 0; i--) { | 2279 for (int i = nof_callbacks - 1; i >= 0; i--) { |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2641 | 2646 |
| 2642 // Emulate [[GetProperty]] semantics for proxies. | 2647 // Emulate [[GetProperty]] semantics for proxies. |
| 2643 bool has_pending_exception; | 2648 bool has_pending_exception; |
| 2644 Handle<Object> argv[] = { result }; | 2649 Handle<Object> argv[] = { result }; |
| 2645 Handle<Object> desc = | 2650 Handle<Object> desc = |
| 2646 Execution::Call(isolate->to_complete_property_descriptor(), result, | 2651 Execution::Call(isolate->to_complete_property_descriptor(), result, |
| 2647 ARRAY_SIZE(argv), argv, &has_pending_exception); | 2652 ARRAY_SIZE(argv), argv, &has_pending_exception); |
| 2648 if (has_pending_exception) return Failure::Exception(); | 2653 if (has_pending_exception) return Failure::Exception(); |
| 2649 | 2654 |
| 2650 // [[GetProperty]] requires to check that all properties are configurable. | 2655 // [[GetProperty]] requires to check that all properties are configurable. |
| 2651 Handle<String> configurable_name = isolate->factory()->LookupOneByteSymbol( | 2656 Handle<String> configurable_name = |
| 2652 STATIC_ASCII_VECTOR("configurable_")); | 2657 isolate->factory()->InternalizeOneByteString( |
| 2658 STATIC_ASCII_VECTOR("configurable_")); |
| 2653 Handle<Object> configurable( | 2659 Handle<Object> configurable( |
| 2654 v8::internal::GetProperty(desc, configurable_name)); | 2660 v8::internal::GetProperty(desc, configurable_name)); |
| 2655 ASSERT(!isolate->has_pending_exception()); | 2661 ASSERT(!isolate->has_pending_exception()); |
| 2656 ASSERT(configurable->IsTrue() || configurable->IsFalse()); | 2662 ASSERT(configurable->IsTrue() || configurable->IsFalse()); |
| 2657 if (configurable->IsFalse()) { | 2663 if (configurable->IsFalse()) { |
| 2658 Handle<String> trap = | 2664 Handle<String> trap = |
| 2659 isolate->factory()->LookupOneByteSymbol( | 2665 isolate->factory()->InternalizeOneByteString( |
| 2660 STATIC_ASCII_VECTOR("getPropertyDescriptor")); | 2666 STATIC_ASCII_VECTOR("getPropertyDescriptor")); |
| 2661 Handle<Object> args[] = { handler, trap, name }; | 2667 Handle<Object> args[] = { handler, trap, name }; |
| 2662 Handle<Object> error = isolate->factory()->NewTypeError( | 2668 Handle<Object> error = isolate->factory()->NewTypeError( |
| 2663 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); | 2669 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); |
| 2664 return isolate->Throw(*error); | 2670 return isolate->Throw(*error); |
| 2665 } | 2671 } |
| 2666 ASSERT(configurable->IsTrue()); | 2672 ASSERT(configurable->IsTrue()); |
| 2667 | 2673 |
| 2668 // Check for DataDescriptor. | 2674 // Check for DataDescriptor. |
| 2669 Handle<String> hasWritable_name = | 2675 Handle<String> hasWritable_name = |
| 2670 isolate->factory()->LookupOneByteSymbol( | 2676 isolate->factory()->InternalizeOneByteString( |
| 2671 STATIC_ASCII_VECTOR("hasWritable_")); | 2677 STATIC_ASCII_VECTOR("hasWritable_")); |
| 2672 Handle<Object> hasWritable(v8::internal::GetProperty(desc, hasWritable_name)); | 2678 Handle<Object> hasWritable(v8::internal::GetProperty(desc, hasWritable_name)); |
| 2673 ASSERT(!isolate->has_pending_exception()); | 2679 ASSERT(!isolate->has_pending_exception()); |
| 2674 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse()); | 2680 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse()); |
| 2675 if (hasWritable->IsTrue()) { | 2681 if (hasWritable->IsTrue()) { |
| 2676 Handle<String> writable_name = | 2682 Handle<String> writable_name = |
| 2677 isolate->factory()->LookupOneByteSymbol( | 2683 isolate->factory()->InternalizeOneByteString( |
| 2678 STATIC_ASCII_VECTOR("writable_")); | 2684 STATIC_ASCII_VECTOR("writable_")); |
| 2679 Handle<Object> writable(v8::internal::GetProperty(desc, writable_name)); | 2685 Handle<Object> writable(v8::internal::GetProperty(desc, writable_name)); |
| 2680 ASSERT(!isolate->has_pending_exception()); | 2686 ASSERT(!isolate->has_pending_exception()); |
| 2681 ASSERT(writable->IsTrue() || writable->IsFalse()); | 2687 ASSERT(writable->IsTrue() || writable->IsFalse()); |
| 2682 *done = writable->IsFalse(); | 2688 *done = writable->IsFalse(); |
| 2683 if (!*done) return GetHeap()->the_hole_value(); | 2689 if (!*done) return GetHeap()->the_hole_value(); |
| 2684 if (strict_mode == kNonStrictMode) return *value; | 2690 if (strict_mode == kNonStrictMode) return *value; |
| 2685 Handle<Object> args[] = { name, receiver }; | 2691 Handle<Object> args[] = { name, receiver }; |
| 2686 Handle<Object> error = isolate->factory()->NewTypeError( | 2692 Handle<Object> error = isolate->factory()->NewTypeError( |
| 2687 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 2693 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
| 2688 return isolate->Throw(*error); | 2694 return isolate->Throw(*error); |
| 2689 } | 2695 } |
| 2690 | 2696 |
| 2691 // We have an AccessorDescriptor. | 2697 // We have an AccessorDescriptor. |
| 2692 Handle<String> set_name = isolate->factory()->LookupOneByteSymbol( | 2698 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( |
| 2693 STATIC_ASCII_VECTOR("set_")); | 2699 STATIC_ASCII_VECTOR("set_")); |
| 2694 Handle<Object> setter(v8::internal::GetProperty(desc, set_name)); | 2700 Handle<Object> setter(v8::internal::GetProperty(desc, set_name)); |
| 2695 ASSERT(!isolate->has_pending_exception()); | 2701 ASSERT(!isolate->has_pending_exception()); |
| 2696 if (!setter->IsUndefined()) { | 2702 if (!setter->IsUndefined()) { |
| 2697 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 2703 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 2698 return receiver->SetPropertyWithDefinedSetter( | 2704 return receiver->SetPropertyWithDefinedSetter( |
| 2699 JSReceiver::cast(*setter), *value); | 2705 JSReceiver::cast(*setter), *value); |
| 2700 } | 2706 } |
| 2701 | 2707 |
| 2702 if (strict_mode == kNonStrictMode) return *value; | 2708 if (strict_mode == kNonStrictMode) return *value; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2715 Handle<Object> name(name_raw); | 2721 Handle<Object> name(name_raw); |
| 2716 | 2722 |
| 2717 Handle<Object> args[] = { name }; | 2723 Handle<Object> args[] = { name }; |
| 2718 Handle<Object> result = CallTrap( | 2724 Handle<Object> result = CallTrap( |
| 2719 "delete", Handle<Object>(), ARRAY_SIZE(args), args); | 2725 "delete", Handle<Object>(), ARRAY_SIZE(args), args); |
| 2720 if (isolate->has_pending_exception()) return Failure::Exception(); | 2726 if (isolate->has_pending_exception()) return Failure::Exception(); |
| 2721 | 2727 |
| 2722 Object* bool_result = result->ToBoolean(); | 2728 Object* bool_result = result->ToBoolean(); |
| 2723 if (mode == STRICT_DELETION && bool_result == GetHeap()->false_value()) { | 2729 if (mode == STRICT_DELETION && bool_result == GetHeap()->false_value()) { |
| 2724 Handle<Object> handler(receiver->handler()); | 2730 Handle<Object> handler(receiver->handler()); |
| 2725 Handle<String> trap_name = isolate->factory()->LookupOneByteSymbol( | 2731 Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( |
| 2726 STATIC_ASCII_VECTOR("delete")); | 2732 STATIC_ASCII_VECTOR("delete")); |
| 2727 Handle<Object> args[] = { handler, trap_name }; | 2733 Handle<Object> args[] = { handler, trap_name }; |
| 2728 Handle<Object> error = isolate->factory()->NewTypeError( | 2734 Handle<Object> error = isolate->factory()->NewTypeError( |
| 2729 "handler_failed", HandleVector(args, ARRAY_SIZE(args))); | 2735 "handler_failed", HandleVector(args, ARRAY_SIZE(args))); |
| 2730 isolate->Throw(*error); | 2736 isolate->Throw(*error); |
| 2731 return Failure::Exception(); | 2737 return Failure::Exception(); |
| 2732 } | 2738 } |
| 2733 return bool_result; | 2739 return bool_result; |
| 2734 } | 2740 } |
| 2735 | 2741 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2762 if (result->IsUndefined()) return ABSENT; | 2768 if (result->IsUndefined()) return ABSENT; |
| 2763 | 2769 |
| 2764 bool has_pending_exception; | 2770 bool has_pending_exception; |
| 2765 Handle<Object> argv[] = { result }; | 2771 Handle<Object> argv[] = { result }; |
| 2766 Handle<Object> desc = | 2772 Handle<Object> desc = |
| 2767 Execution::Call(isolate->to_complete_property_descriptor(), result, | 2773 Execution::Call(isolate->to_complete_property_descriptor(), result, |
| 2768 ARRAY_SIZE(argv), argv, &has_pending_exception); | 2774 ARRAY_SIZE(argv), argv, &has_pending_exception); |
| 2769 if (has_pending_exception) return NONE; | 2775 if (has_pending_exception) return NONE; |
| 2770 | 2776 |
| 2771 // Convert result to PropertyAttributes. | 2777 // Convert result to PropertyAttributes. |
| 2772 Handle<String> enum_n = isolate->factory()->LookupOneByteSymbol( | 2778 Handle<String> enum_n = isolate->factory()->InternalizeOneByteString( |
| 2773 STATIC_ASCII_VECTOR("enumerable")); | 2779 STATIC_ASCII_VECTOR("enumerable")); |
| 2774 Handle<Object> enumerable(v8::internal::GetProperty(desc, enum_n)); | 2780 Handle<Object> enumerable(v8::internal::GetProperty(desc, enum_n)); |
| 2775 if (isolate->has_pending_exception()) return NONE; | 2781 if (isolate->has_pending_exception()) return NONE; |
| 2776 Handle<String> conf_n = isolate->factory()->LookupOneByteSymbol( | 2782 Handle<String> conf_n = isolate->factory()->InternalizeOneByteString( |
| 2777 STATIC_ASCII_VECTOR("configurable")); | 2783 STATIC_ASCII_VECTOR("configurable")); |
| 2778 Handle<Object> configurable(v8::internal::GetProperty(desc, conf_n)); | 2784 Handle<Object> configurable(v8::internal::GetProperty(desc, conf_n)); |
| 2779 if (isolate->has_pending_exception()) return NONE; | 2785 if (isolate->has_pending_exception()) return NONE; |
| 2780 Handle<String> writ_n = isolate->factory()->LookupOneByteSymbol( | 2786 Handle<String> writ_n = isolate->factory()->InternalizeOneByteString( |
| 2781 STATIC_ASCII_VECTOR("writable")); | 2787 STATIC_ASCII_VECTOR("writable")); |
| 2782 Handle<Object> writable(v8::internal::GetProperty(desc, writ_n)); | 2788 Handle<Object> writable(v8::internal::GetProperty(desc, writ_n)); |
| 2783 if (isolate->has_pending_exception()) return NONE; | 2789 if (isolate->has_pending_exception()) return NONE; |
| 2784 | 2790 |
| 2785 if (configurable->IsFalse()) { | 2791 if (configurable->IsFalse()) { |
| 2786 Handle<String> trap = isolate->factory()->LookupOneByteSymbol( | 2792 Handle<String> trap = isolate->factory()->InternalizeOneByteString( |
| 2787 STATIC_ASCII_VECTOR("getPropertyDescriptor")); | 2793 STATIC_ASCII_VECTOR("getPropertyDescriptor")); |
| 2788 Handle<Object> args[] = { handler, trap, name }; | 2794 Handle<Object> args[] = { handler, trap, name }; |
| 2789 Handle<Object> error = isolate->factory()->NewTypeError( | 2795 Handle<Object> error = isolate->factory()->NewTypeError( |
| 2790 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); | 2796 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); |
| 2791 isolate->Throw(*error); | 2797 isolate->Throw(*error); |
| 2792 return NONE; | 2798 return NONE; |
| 2793 } | 2799 } |
| 2794 | 2800 |
| 2795 int attributes = NONE; | 2801 int attributes = NONE; |
| 2796 if (enumerable->ToBoolean()->IsFalse()) attributes |= DONT_ENUM; | 2802 if (enumerable->ToBoolean()->IsFalse()) attributes |= DONT_ENUM; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2837 } | 2843 } |
| 2838 | 2844 |
| 2839 | 2845 |
| 2840 MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name, | 2846 MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name, |
| 2841 Handle<Object> derived, | 2847 Handle<Object> derived, |
| 2842 int argc, | 2848 int argc, |
| 2843 Handle<Object> argv[]) { | 2849 Handle<Object> argv[]) { |
| 2844 Isolate* isolate = GetIsolate(); | 2850 Isolate* isolate = GetIsolate(); |
| 2845 Handle<Object> handler(this->handler()); | 2851 Handle<Object> handler(this->handler()); |
| 2846 | 2852 |
| 2847 Handle<String> trap_name = isolate->factory()->LookupUtf8Symbol(name); | 2853 Handle<String> trap_name = isolate->factory()->InternalizeUtf8String(name); |
| 2848 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); | 2854 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); |
| 2849 if (isolate->has_pending_exception()) return trap; | 2855 if (isolate->has_pending_exception()) return trap; |
| 2850 | 2856 |
| 2851 if (trap->IsUndefined()) { | 2857 if (trap->IsUndefined()) { |
| 2852 if (derived.is_null()) { | 2858 if (derived.is_null()) { |
| 2853 Handle<Object> args[] = { handler, trap_name }; | 2859 Handle<Object> args[] = { handler, trap_name }; |
| 2854 Handle<Object> error = isolate->factory()->NewTypeError( | 2860 Handle<Object> error = isolate->factory()->NewTypeError( |
| 2855 "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args))); | 2861 "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args))); |
| 2856 isolate->Throw(*error); | 2862 isolate->Throw(*error); |
| 2857 return Handle<Object>(); | 2863 return Handle<Object>(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2878 PropertyAttributes attributes, | 2884 PropertyAttributes attributes, |
| 2879 StrictModeFlag strict_mode, | 2885 StrictModeFlag strict_mode, |
| 2880 StoreFromKeyed store_mode) { | 2886 StoreFromKeyed store_mode) { |
| 2881 Heap* heap = GetHeap(); | 2887 Heap* heap = GetHeap(); |
| 2882 Isolate* isolate = heap->isolate(); | 2888 Isolate* isolate = heap->isolate(); |
| 2883 // Make sure that the top context does not change when doing callbacks or | 2889 // Make sure that the top context does not change when doing callbacks or |
| 2884 // interceptor calls. | 2890 // interceptor calls. |
| 2885 AssertNoContextChange ncc; | 2891 AssertNoContextChange ncc; |
| 2886 | 2892 |
| 2887 // Optimization for 2-byte strings often used as keys in a decompression | 2893 // Optimization for 2-byte strings often used as keys in a decompression |
| 2888 // dictionary. We make these short keys into symbols to avoid constantly | 2894 // dictionary. We internalize these short keys to avoid constantly |
| 2889 // reallocating them. | 2895 // reallocating them. |
| 2890 if (!name_raw->IsSymbol() && name_raw->length() <= 2) { | 2896 if (!name_raw->IsInternalizedString() && name_raw->length() <= 2) { |
| 2891 Object* symbol_version; | 2897 Object* internalized_version; |
| 2892 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name_raw); | 2898 { MaybeObject* maybe_string_version = heap->InternalizeString(name_raw); |
| 2893 if (maybe_symbol_version->ToObject(&symbol_version)) { | 2899 if (maybe_string_version->ToObject(&internalized_version)) { |
| 2894 name_raw = String::cast(symbol_version); | 2900 name_raw = String::cast(internalized_version); |
| 2895 } | 2901 } |
| 2896 } | 2902 } |
| 2897 } | 2903 } |
| 2898 | 2904 |
| 2899 // Check access rights if needed. | 2905 // Check access rights if needed. |
| 2900 if (IsAccessCheckNeeded()) { | 2906 if (IsAccessCheckNeeded()) { |
| 2901 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { | 2907 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { |
| 2902 return SetPropertyWithFailedAccessCheck( | 2908 return SetPropertyWithFailedAccessCheck( |
| 2903 lookup, name_raw, value_raw, true, strict_mode); | 2909 lookup, name_raw, value_raw, true, strict_mode); |
| 2904 } | 2910 } |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3764 hash_value = V8::RandomPrivate(isolate) & Smi::kMaxValue; | 3770 hash_value = V8::RandomPrivate(isolate) & Smi::kMaxValue; |
| 3765 attempts++; | 3771 attempts++; |
| 3766 } while (hash_value == 0 && attempts < 30); | 3772 } while (hash_value == 0 && attempts < 30); |
| 3767 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 | 3773 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 |
| 3768 | 3774 |
| 3769 return Smi::FromInt(hash_value); | 3775 return Smi::FromInt(hash_value); |
| 3770 } | 3776 } |
| 3771 | 3777 |
| 3772 | 3778 |
| 3773 MaybeObject* JSObject::SetIdentityHash(Smi* hash, CreationFlag flag) { | 3779 MaybeObject* JSObject::SetIdentityHash(Smi* hash, CreationFlag flag) { |
| 3774 MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_symbol(), | 3780 MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_string(), |
| 3775 hash); | 3781 hash); |
| 3776 if (maybe->IsFailure()) return maybe; | 3782 if (maybe->IsFailure()) return maybe; |
| 3777 return this; | 3783 return this; |
| 3778 } | 3784 } |
| 3779 | 3785 |
| 3780 | 3786 |
| 3781 int JSObject::GetIdentityHash(Handle<JSObject> obj) { | 3787 int JSObject::GetIdentityHash(Handle<JSObject> obj) { |
| 3782 CALL_AND_RETRY(obj->GetIsolate(), | 3788 CALL_AND_RETRY(obj->GetIsolate(), |
| 3783 obj->GetIdentityHash(ALLOW_CREATION), | 3789 obj->GetIdentityHash(ALLOW_CREATION), |
| 3784 return Smi::cast(__object__)->value(), | 3790 return Smi::cast(__object__)->value(), |
| 3785 return 0); | 3791 return 0); |
| 3786 } | 3792 } |
| 3787 | 3793 |
| 3788 | 3794 |
| 3789 MaybeObject* JSObject::GetIdentityHash(CreationFlag flag) { | 3795 MaybeObject* JSObject::GetIdentityHash(CreationFlag flag) { |
| 3790 Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_symbol()); | 3796 Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_string()); |
| 3791 if (stored_value->IsSmi()) return stored_value; | 3797 if (stored_value->IsSmi()) return stored_value; |
| 3792 | 3798 |
| 3793 // Do not generate permanent identity hash code if not requested. | 3799 // Do not generate permanent identity hash code if not requested. |
| 3794 if (flag == OMIT_CREATION) return GetHeap()->undefined_value(); | 3800 if (flag == OMIT_CREATION) return GetHeap()->undefined_value(); |
| 3795 | 3801 |
| 3796 Smi* hash = GenerateIdentityHash(); | 3802 Smi* hash = GenerateIdentityHash(); |
| 3797 MaybeObject* result = SetHiddenProperty(GetHeap()->identity_hash_symbol(), | 3803 MaybeObject* result = SetHiddenProperty(GetHeap()->identity_hash_string(), |
| 3798 hash); | 3804 hash); |
| 3799 if (result->IsFailure()) return result; | 3805 if (result->IsFailure()) return result; |
| 3800 if (result->ToObjectUnchecked()->IsUndefined()) { | 3806 if (result->ToObjectUnchecked()->IsUndefined()) { |
| 3801 // Trying to get hash of detached proxy. | 3807 // Trying to get hash of detached proxy. |
| 3802 return Smi::FromInt(0); | 3808 return Smi::FromInt(0); |
| 3803 } | 3809 } |
| 3804 return hash; | 3810 return hash; |
| 3805 } | 3811 } |
| 3806 | 3812 |
| 3807 | 3813 |
| 3808 MaybeObject* JSProxy::GetIdentityHash(CreationFlag flag) { | 3814 MaybeObject* JSProxy::GetIdentityHash(CreationFlag flag) { |
| 3809 Object* hash = this->hash(); | 3815 Object* hash = this->hash(); |
| 3810 if (!hash->IsSmi() && flag == ALLOW_CREATION) { | 3816 if (!hash->IsSmi() && flag == ALLOW_CREATION) { |
| 3811 hash = GenerateIdentityHash(); | 3817 hash = GenerateIdentityHash(); |
| 3812 set_hash(hash); | 3818 set_hash(hash); |
| 3813 } | 3819 } |
| 3814 return hash; | 3820 return hash; |
| 3815 } | 3821 } |
| 3816 | 3822 |
| 3817 | 3823 |
| 3818 Object* JSObject::GetHiddenProperty(String* key) { | 3824 Object* JSObject::GetHiddenProperty(String* key) { |
| 3819 ASSERT(key->IsSymbol()); | 3825 ASSERT(key->IsInternalizedString()); |
| 3820 if (IsJSGlobalProxy()) { | 3826 if (IsJSGlobalProxy()) { |
| 3821 // For a proxy, use the prototype as target object. | 3827 // For a proxy, use the prototype as target object. |
| 3822 Object* proxy_parent = GetPrototype(); | 3828 Object* proxy_parent = GetPrototype(); |
| 3823 // If the proxy is detached, return undefined. | 3829 // If the proxy is detached, return undefined. |
| 3824 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); | 3830 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); |
| 3825 ASSERT(proxy_parent->IsJSGlobalObject()); | 3831 ASSERT(proxy_parent->IsJSGlobalObject()); |
| 3826 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); | 3832 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); |
| 3827 } | 3833 } |
| 3828 ASSERT(!IsJSGlobalProxy()); | 3834 ASSERT(!IsJSGlobalProxy()); |
| 3829 MaybeObject* hidden_lookup = | 3835 MaybeObject* hidden_lookup = |
| 3830 GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); | 3836 GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); |
| 3831 Object* inline_value = hidden_lookup->ToObjectUnchecked(); | 3837 Object* inline_value = hidden_lookup->ToObjectUnchecked(); |
| 3832 | 3838 |
| 3833 if (inline_value->IsSmi()) { | 3839 if (inline_value->IsSmi()) { |
| 3834 // Handle inline-stored identity hash. | 3840 // Handle inline-stored identity hash. |
| 3835 if (key == GetHeap()->identity_hash_symbol()) { | 3841 if (key == GetHeap()->identity_hash_string()) { |
| 3836 return inline_value; | 3842 return inline_value; |
| 3837 } else { | 3843 } else { |
| 3838 return GetHeap()->undefined_value(); | 3844 return GetHeap()->undefined_value(); |
| 3839 } | 3845 } |
| 3840 } | 3846 } |
| 3841 | 3847 |
| 3842 if (inline_value->IsUndefined()) return GetHeap()->undefined_value(); | 3848 if (inline_value->IsUndefined()) return GetHeap()->undefined_value(); |
| 3843 | 3849 |
| 3844 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); | 3850 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); |
| 3845 Object* entry = hashtable->Lookup(key); | 3851 Object* entry = hashtable->Lookup(key); |
| 3846 if (entry->IsTheHole()) return GetHeap()->undefined_value(); | 3852 if (entry->IsTheHole()) return GetHeap()->undefined_value(); |
| 3847 return entry; | 3853 return entry; |
| 3848 } | 3854 } |
| 3849 | 3855 |
| 3850 | 3856 |
| 3851 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj, | 3857 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj, |
| 3852 Handle<String> key, | 3858 Handle<String> key, |
| 3853 Handle<Object> value) { | 3859 Handle<Object> value) { |
| 3854 CALL_HEAP_FUNCTION(obj->GetIsolate(), | 3860 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| 3855 obj->SetHiddenProperty(*key, *value), | 3861 obj->SetHiddenProperty(*key, *value), |
| 3856 Object); | 3862 Object); |
| 3857 } | 3863 } |
| 3858 | 3864 |
| 3859 | 3865 |
| 3860 MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) { | 3866 MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) { |
| 3861 ASSERT(key->IsSymbol()); | 3867 ASSERT(key->IsInternalizedString()); |
| 3862 if (IsJSGlobalProxy()) { | 3868 if (IsJSGlobalProxy()) { |
| 3863 // For a proxy, use the prototype as target object. | 3869 // For a proxy, use the prototype as target object. |
| 3864 Object* proxy_parent = GetPrototype(); | 3870 Object* proxy_parent = GetPrototype(); |
| 3865 // If the proxy is detached, return undefined. | 3871 // If the proxy is detached, return undefined. |
| 3866 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); | 3872 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); |
| 3867 ASSERT(proxy_parent->IsJSGlobalObject()); | 3873 ASSERT(proxy_parent->IsJSGlobalObject()); |
| 3868 return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value); | 3874 return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value); |
| 3869 } | 3875 } |
| 3870 ASSERT(!IsJSGlobalProxy()); | 3876 ASSERT(!IsJSGlobalProxy()); |
| 3871 MaybeObject* hidden_lookup = | 3877 MaybeObject* hidden_lookup = |
| 3872 GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); | 3878 GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); |
| 3873 Object* inline_value = hidden_lookup->ToObjectUnchecked(); | 3879 Object* inline_value = hidden_lookup->ToObjectUnchecked(); |
| 3874 | 3880 |
| 3875 // If there is no backing store yet, store the identity hash inline. | 3881 // If there is no backing store yet, store the identity hash inline. |
| 3876 if (value->IsSmi() && | 3882 if (value->IsSmi() && |
| 3877 key == GetHeap()->identity_hash_symbol() && | 3883 key == GetHeap()->identity_hash_string() && |
| 3878 (inline_value->IsUndefined() || inline_value->IsSmi())) { | 3884 (inline_value->IsUndefined() || inline_value->IsSmi())) { |
| 3879 return SetHiddenPropertiesHashTable(value); | 3885 return SetHiddenPropertiesHashTable(value); |
| 3880 } | 3886 } |
| 3881 | 3887 |
| 3882 hidden_lookup = GetHiddenPropertiesHashTable(CREATE_NEW_IF_ABSENT); | 3888 hidden_lookup = GetHiddenPropertiesHashTable(CREATE_NEW_IF_ABSENT); |
| 3883 ObjectHashTable* hashtable; | 3889 ObjectHashTable* hashtable; |
| 3884 if (!hidden_lookup->To(&hashtable)) return hidden_lookup; | 3890 if (!hidden_lookup->To(&hashtable)) return hidden_lookup; |
| 3885 | 3891 |
| 3886 // If it was found, check if the key is already in the dictionary. | 3892 // If it was found, check if the key is already in the dictionary. |
| 3887 MaybeObject* insert_result = hashtable->Put(key, value); | 3893 MaybeObject* insert_result = hashtable->Put(key, value); |
| 3888 ObjectHashTable* new_table; | 3894 ObjectHashTable* new_table; |
| 3889 if (!insert_result->To(&new_table)) return insert_result; | 3895 if (!insert_result->To(&new_table)) return insert_result; |
| 3890 if (new_table != hashtable) { | 3896 if (new_table != hashtable) { |
| 3891 // If adding the key expanded the dictionary (i.e., Add returned a new | 3897 // If adding the key expanded the dictionary (i.e., Add returned a new |
| 3892 // dictionary), store it back to the object. | 3898 // dictionary), store it back to the object. |
| 3893 MaybeObject* store_result = SetHiddenPropertiesHashTable(new_table); | 3899 MaybeObject* store_result = SetHiddenPropertiesHashTable(new_table); |
| 3894 if (store_result->IsFailure()) return store_result; | 3900 if (store_result->IsFailure()) return store_result; |
| 3895 } | 3901 } |
| 3896 // Return this to mark success. | 3902 // Return this to mark success. |
| 3897 return this; | 3903 return this; |
| 3898 } | 3904 } |
| 3899 | 3905 |
| 3900 | 3906 |
| 3901 void JSObject::DeleteHiddenProperty(String* key) { | 3907 void JSObject::DeleteHiddenProperty(String* key) { |
| 3902 ASSERT(key->IsSymbol()); | 3908 ASSERT(key->IsInternalizedString()); |
| 3903 if (IsJSGlobalProxy()) { | 3909 if (IsJSGlobalProxy()) { |
| 3904 // For a proxy, use the prototype as target object. | 3910 // For a proxy, use the prototype as target object. |
| 3905 Object* proxy_parent = GetPrototype(); | 3911 Object* proxy_parent = GetPrototype(); |
| 3906 // If the proxy is detached, return immediately. | 3912 // If the proxy is detached, return immediately. |
| 3907 if (proxy_parent->IsNull()) return; | 3913 if (proxy_parent->IsNull()) return; |
| 3908 ASSERT(proxy_parent->IsJSGlobalObject()); | 3914 ASSERT(proxy_parent->IsJSGlobalObject()); |
| 3909 JSObject::cast(proxy_parent)->DeleteHiddenProperty(key); | 3915 JSObject::cast(proxy_parent)->DeleteHiddenProperty(key); |
| 3910 return; | 3916 return; |
| 3911 } | 3917 } |
| 3912 ASSERT(!IsJSGlobalProxy()); | 3918 ASSERT(!IsJSGlobalProxy()); |
| 3913 MaybeObject* hidden_lookup = | 3919 MaybeObject* hidden_lookup = |
| 3914 GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); | 3920 GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); |
| 3915 Object* inline_value = hidden_lookup->ToObjectUnchecked(); | 3921 Object* inline_value = hidden_lookup->ToObjectUnchecked(); |
| 3916 | 3922 |
| 3917 // We never delete (inline-stored) identity hashes. | 3923 // We never delete (inline-stored) identity hashes. |
| 3918 ASSERT(key != GetHeap()->identity_hash_symbol()); | 3924 ASSERT(key != GetHeap()->identity_hash_string()); |
| 3919 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; | 3925 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; |
| 3920 | 3926 |
| 3921 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); | 3927 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); |
| 3922 MaybeObject* delete_result = hashtable->Put(key, GetHeap()->the_hole_value()); | 3928 MaybeObject* delete_result = hashtable->Put(key, GetHeap()->the_hole_value()); |
| 3923 USE(delete_result); | 3929 USE(delete_result); |
| 3924 ASSERT(!delete_result->IsFailure()); // Delete does not cause GC. | 3930 ASSERT(!delete_result->IsFailure()); // Delete does not cause GC. |
| 3925 } | 3931 } |
| 3926 | 3932 |
| 3927 | 3933 |
| 3928 bool JSObject::HasHiddenProperties() { | 3934 bool JSObject::HasHiddenProperties() { |
| 3929 return GetPropertyAttributePostInterceptor(this, | 3935 return GetPropertyAttributePostInterceptor(this, |
| 3930 GetHeap()->hidden_symbol(), | 3936 GetHeap()->hidden_string(), |
| 3931 false) != ABSENT; | 3937 false) != ABSENT; |
| 3932 } | 3938 } |
| 3933 | 3939 |
| 3934 | 3940 |
| 3935 MaybeObject* JSObject::GetHiddenPropertiesHashTable( | 3941 MaybeObject* JSObject::GetHiddenPropertiesHashTable( |
| 3936 InitializeHiddenProperties init_option) { | 3942 InitializeHiddenProperties init_option) { |
| 3937 ASSERT(!IsJSGlobalProxy()); | 3943 ASSERT(!IsJSGlobalProxy()); |
| 3938 Object* inline_value; | 3944 Object* inline_value; |
| 3939 if (HasFastProperties()) { | 3945 if (HasFastProperties()) { |
| 3940 // If the object has fast properties, check whether the first slot | 3946 // If the object has fast properties, check whether the first slot |
| 3941 // in the descriptor array matches the hidden symbol. Since the | 3947 // in the descriptor array matches the hidden string. Since the |
| 3942 // hidden symbols hash code is zero (and no other string has hash | 3948 // hidden strings hash code is zero (and no other string has hash |
| 3943 // code zero) it will always occupy the first entry if present. | 3949 // code zero) it will always occupy the first entry if present. |
| 3944 DescriptorArray* descriptors = this->map()->instance_descriptors(); | 3950 DescriptorArray* descriptors = this->map()->instance_descriptors(); |
| 3945 if (descriptors->number_of_descriptors() > 0) { | 3951 if (descriptors->number_of_descriptors() > 0) { |
| 3946 int sorted_index = descriptors->GetSortedKeyIndex(0); | 3952 int sorted_index = descriptors->GetSortedKeyIndex(0); |
| 3947 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_symbol() && | 3953 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && |
| 3948 sorted_index < map()->NumberOfOwnDescriptors()) { | 3954 sorted_index < map()->NumberOfOwnDescriptors()) { |
| 3949 ASSERT(descriptors->GetType(sorted_index) == FIELD); | 3955 ASSERT(descriptors->GetType(sorted_index) == FIELD); |
| 3950 inline_value = | 3956 inline_value = |
| 3951 this->FastPropertyAt(descriptors->GetFieldIndex(sorted_index)); | 3957 this->FastPropertyAt(descriptors->GetFieldIndex(sorted_index)); |
| 3952 } else { | 3958 } else { |
| 3953 inline_value = GetHeap()->undefined_value(); | 3959 inline_value = GetHeap()->undefined_value(); |
| 3954 } | 3960 } |
| 3955 } else { | 3961 } else { |
| 3956 inline_value = GetHeap()->undefined_value(); | 3962 inline_value = GetHeap()->undefined_value(); |
| 3957 } | 3963 } |
| 3958 } else { | 3964 } else { |
| 3959 PropertyAttributes attributes; | 3965 PropertyAttributes attributes; |
| 3960 // You can't install a getter on a property indexed by the hidden symbol, | 3966 // You can't install a getter on a property indexed by the hidden string, |
| 3961 // so we can be sure that GetLocalPropertyPostInterceptor returns a real | 3967 // so we can be sure that GetLocalPropertyPostInterceptor returns a real |
| 3962 // object. | 3968 // object. |
| 3963 inline_value = | 3969 inline_value = |
| 3964 GetLocalPropertyPostInterceptor(this, | 3970 GetLocalPropertyPostInterceptor(this, |
| 3965 GetHeap()->hidden_symbol(), | 3971 GetHeap()->hidden_string(), |
| 3966 &attributes)->ToObjectUnchecked(); | 3972 &attributes)->ToObjectUnchecked(); |
| 3967 } | 3973 } |
| 3968 | 3974 |
| 3969 if (init_option == ONLY_RETURN_INLINE_VALUE || | 3975 if (init_option == ONLY_RETURN_INLINE_VALUE || |
| 3970 inline_value->IsHashTable()) { | 3976 inline_value->IsHashTable()) { |
| 3971 return inline_value; | 3977 return inline_value; |
| 3972 } | 3978 } |
| 3973 | 3979 |
| 3974 ObjectHashTable* hashtable; | 3980 ObjectHashTable* hashtable; |
| 3975 static const int kInitialCapacity = 4; | 3981 static const int kInitialCapacity = 4; |
| 3976 MaybeObject* maybe_obj = | 3982 MaybeObject* maybe_obj = |
| 3977 ObjectHashTable::Allocate(kInitialCapacity, | 3983 ObjectHashTable::Allocate(kInitialCapacity, |
| 3978 ObjectHashTable::USE_CUSTOM_MINIMUM_CAPACITY); | 3984 ObjectHashTable::USE_CUSTOM_MINIMUM_CAPACITY); |
| 3979 if (!maybe_obj->To<ObjectHashTable>(&hashtable)) return maybe_obj; | 3985 if (!maybe_obj->To<ObjectHashTable>(&hashtable)) return maybe_obj; |
| 3980 | 3986 |
| 3981 if (inline_value->IsSmi()) { | 3987 if (inline_value->IsSmi()) { |
| 3982 // We were storing the identity hash inline and now allocated an actual | 3988 // We were storing the identity hash inline and now allocated an actual |
| 3983 // dictionary. Put the identity hash into the new dictionary. | 3989 // dictionary. Put the identity hash into the new dictionary. |
| 3984 MaybeObject* insert_result = | 3990 MaybeObject* insert_result = |
| 3985 hashtable->Put(GetHeap()->identity_hash_symbol(), inline_value); | 3991 hashtable->Put(GetHeap()->identity_hash_string(), inline_value); |
| 3986 ObjectHashTable* new_table; | 3992 ObjectHashTable* new_table; |
| 3987 if (!insert_result->To(&new_table)) return insert_result; | 3993 if (!insert_result->To(&new_table)) return insert_result; |
| 3988 // We expect no resizing for the first insert. | 3994 // We expect no resizing for the first insert. |
| 3989 ASSERT_EQ(hashtable, new_table); | 3995 ASSERT_EQ(hashtable, new_table); |
| 3990 } | 3996 } |
| 3991 | 3997 |
| 3992 MaybeObject* store_result = | 3998 MaybeObject* store_result = |
| 3993 SetPropertyPostInterceptor(GetHeap()->hidden_symbol(), | 3999 SetPropertyPostInterceptor(GetHeap()->hidden_string(), |
| 3994 hashtable, | 4000 hashtable, |
| 3995 DONT_ENUM, | 4001 DONT_ENUM, |
| 3996 kNonStrictMode, | 4002 kNonStrictMode, |
| 3997 OMIT_EXTENSIBILITY_CHECK); | 4003 OMIT_EXTENSIBILITY_CHECK); |
| 3998 if (store_result->IsFailure()) return store_result; | 4004 if (store_result->IsFailure()) return store_result; |
| 3999 return hashtable; | 4005 return hashtable; |
| 4000 } | 4006 } |
| 4001 | 4007 |
| 4002 | 4008 |
| 4003 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { | 4009 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { |
| 4004 ASSERT(!IsJSGlobalProxy()); | 4010 ASSERT(!IsJSGlobalProxy()); |
| 4005 // We can store the identity hash inline iff there is no backing store | 4011 // We can store the identity hash inline iff there is no backing store |
| 4006 // for hidden properties yet. | 4012 // for hidden properties yet. |
| 4007 ASSERT(HasHiddenProperties() != value->IsSmi()); | 4013 ASSERT(HasHiddenProperties() != value->IsSmi()); |
| 4008 if (HasFastProperties()) { | 4014 if (HasFastProperties()) { |
| 4009 // If the object has fast properties, check whether the first slot | 4015 // If the object has fast properties, check whether the first slot |
| 4010 // in the descriptor array matches the hidden symbol. Since the | 4016 // in the descriptor array matches the hidden string. Since the |
| 4011 // hidden symbols hash code is zero (and no other string has hash | 4017 // hidden strings hash code is zero (and no other string has hash |
| 4012 // code zero) it will always occupy the first entry if present. | 4018 // code zero) it will always occupy the first entry if present. |
| 4013 DescriptorArray* descriptors = this->map()->instance_descriptors(); | 4019 DescriptorArray* descriptors = this->map()->instance_descriptors(); |
| 4014 if (descriptors->number_of_descriptors() > 0) { | 4020 if (descriptors->number_of_descriptors() > 0) { |
| 4015 int sorted_index = descriptors->GetSortedKeyIndex(0); | 4021 int sorted_index = descriptors->GetSortedKeyIndex(0); |
| 4016 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_symbol() && | 4022 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && |
| 4017 sorted_index < map()->NumberOfOwnDescriptors()) { | 4023 sorted_index < map()->NumberOfOwnDescriptors()) { |
| 4018 ASSERT(descriptors->GetType(sorted_index) == FIELD); | 4024 ASSERT(descriptors->GetType(sorted_index) == FIELD); |
| 4019 this->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), | 4025 this->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), |
| 4020 value); | 4026 value); |
| 4021 return this; | 4027 return this; |
| 4022 } | 4028 } |
| 4023 } | 4029 } |
| 4024 } | 4030 } |
| 4025 MaybeObject* store_result = | 4031 MaybeObject* store_result = |
| 4026 SetPropertyPostInterceptor(GetHeap()->hidden_symbol(), | 4032 SetPropertyPostInterceptor(GetHeap()->hidden_string(), |
| 4027 value, | 4033 value, |
| 4028 DONT_ENUM, | 4034 DONT_ENUM, |
| 4029 kNonStrictMode, | 4035 kNonStrictMode, |
| 4030 OMIT_EXTENSIBILITY_CHECK); | 4036 OMIT_EXTENSIBILITY_CHECK); |
| 4031 if (store_result->IsFailure()) return store_result; | 4037 if (store_result->IsFailure()) return store_result; |
| 4032 return this; | 4038 return this; |
| 4033 } | 4039 } |
| 4034 | 4040 |
| 4035 | 4041 |
| 4036 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, | 4042 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4580 | 4586 |
| 4581 // Do not use inline caching if the object is a non-global object | 4587 // Do not use inline caching if the object is a non-global object |
| 4582 // that requires access checks. | 4588 // that requires access checks. |
| 4583 if (IsAccessCheckNeeded()) { | 4589 if (IsAccessCheckNeeded()) { |
| 4584 result->DisallowCaching(); | 4590 result->DisallowCaching(); |
| 4585 } | 4591 } |
| 4586 | 4592 |
| 4587 JSObject* js_object = JSObject::cast(this); | 4593 JSObject* js_object = JSObject::cast(this); |
| 4588 | 4594 |
| 4589 // Check __proto__ before interceptor. | 4595 // Check __proto__ before interceptor. |
| 4590 if (name->Equals(heap->Proto_symbol()) && !IsJSContextExtensionObject()) { | 4596 if (name->Equals(heap->proto_string()) && !IsJSContextExtensionObject()) { |
| 4591 result->ConstantResult(js_object); | 4597 result->ConstantResult(js_object); |
| 4592 return; | 4598 return; |
| 4593 } | 4599 } |
| 4594 | 4600 |
| 4595 // Check for lookup interceptor except when bootstrapping. | 4601 // Check for lookup interceptor except when bootstrapping. |
| 4596 if (js_object->HasNamedInterceptor() && | 4602 if (js_object->HasNamedInterceptor() && |
| 4597 !heap->isolate()->bootstrapper()->IsActive()) { | 4603 !heap->isolate()->bootstrapper()->IsActive()) { |
| 4598 result->InterceptorResult(js_object); | 4604 result->InterceptorResult(js_object); |
| 4599 return; | 4605 return; |
| 4600 } | 4606 } |
| (...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5481 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | 5487 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
| 5482 | 5488 |
| 5483 return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0); | 5489 return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0); |
| 5484 } | 5490 } |
| 5485 | 5491 |
| 5486 | 5492 |
| 5487 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, | 5493 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, |
| 5488 TransitionFlag flag) { | 5494 TransitionFlag flag) { |
| 5489 DescriptorArray* descriptors = instance_descriptors(); | 5495 DescriptorArray* descriptors = instance_descriptors(); |
| 5490 | 5496 |
| 5491 // Ensure the key is a symbol. | 5497 // Ensure the key is an internalized string. |
| 5492 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); | 5498 MaybeObject* maybe_failure = descriptor->KeyToInternalizedString(); |
| 5493 if (maybe_failure->IsFailure()) return maybe_failure; | 5499 if (maybe_failure->IsFailure()) return maybe_failure; |
| 5494 | 5500 |
| 5495 int old_size = NumberOfOwnDescriptors(); | 5501 int old_size = NumberOfOwnDescriptors(); |
| 5496 int new_size = old_size + 1; | 5502 int new_size = old_size + 1; |
| 5497 descriptor->SetEnumerationIndex(new_size); | 5503 descriptor->SetEnumerationIndex(new_size); |
| 5498 | 5504 |
| 5499 if (flag == INSERT_TRANSITION && | 5505 if (flag == INSERT_TRANSITION && |
| 5500 owns_descriptors() && | 5506 owns_descriptors() && |
| 5501 CanHaveMoreTransitions()) { | 5507 CanHaveMoreTransitions()) { |
| 5502 return ShareDescriptor(descriptors, descriptor); | 5508 return ShareDescriptor(descriptors, descriptor); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 5525 int insertion_index = new_descriptors->number_of_descriptors() - 1; | 5531 int insertion_index = new_descriptors->number_of_descriptors() - 1; |
| 5526 | 5532 |
| 5527 return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index); | 5533 return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index); |
| 5528 } | 5534 } |
| 5529 | 5535 |
| 5530 | 5536 |
| 5531 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, | 5537 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, |
| 5532 TransitionFlag flag) { | 5538 TransitionFlag flag) { |
| 5533 DescriptorArray* old_descriptors = instance_descriptors(); | 5539 DescriptorArray* old_descriptors = instance_descriptors(); |
| 5534 | 5540 |
| 5535 // Ensure the key is a symbol. | 5541 // Ensure the key is an internalized string. |
| 5536 MaybeObject* maybe_result = descriptor->KeyToSymbol(); | 5542 MaybeObject* maybe_result = descriptor->KeyToInternalizedString(); |
| 5537 if (maybe_result->IsFailure()) return maybe_result; | 5543 if (maybe_result->IsFailure()) return maybe_result; |
| 5538 | 5544 |
| 5539 // We replace the key if it is already present. | 5545 // We replace the key if it is already present. |
| 5540 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); | 5546 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); |
| 5541 if (index != DescriptorArray::kNotFound) { | 5547 if (index != DescriptorArray::kNotFound) { |
| 5542 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag); | 5548 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag); |
| 5543 } | 5549 } |
| 5544 return CopyAddDescriptor(descriptor, flag); | 5550 return CopyAddDescriptor(descriptor, flag); |
| 5545 } | 5551 } |
| 5546 | 5552 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5562 if (number_of_descriptors() != enumeration_index) descriptors->Sort(); | 5568 if (number_of_descriptors() != enumeration_index) descriptors->Sort(); |
| 5563 | 5569 |
| 5564 return descriptors; | 5570 return descriptors; |
| 5565 } | 5571 } |
| 5566 | 5572 |
| 5567 | 5573 |
| 5568 MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors, | 5574 MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors, |
| 5569 Descriptor* descriptor, | 5575 Descriptor* descriptor, |
| 5570 int insertion_index, | 5576 int insertion_index, |
| 5571 TransitionFlag flag) { | 5577 TransitionFlag flag) { |
| 5572 // Ensure the key is a symbol. | 5578 // Ensure the key is an internalized string. |
| 5573 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); | 5579 MaybeObject* maybe_failure = descriptor->KeyToInternalizedString(); |
| 5574 if (maybe_failure->IsFailure()) return maybe_failure; | 5580 if (maybe_failure->IsFailure()) return maybe_failure; |
| 5575 | 5581 |
| 5576 String* key = descriptor->GetKey(); | 5582 String* key = descriptor->GetKey(); |
| 5577 ASSERT(key == descriptors->GetKey(insertion_index)); | 5583 ASSERT(key == descriptors->GetKey(insertion_index)); |
| 5578 | 5584 |
| 5579 int new_size = NumberOfOwnDescriptors(); | 5585 int new_size = NumberOfOwnDescriptors(); |
| 5580 ASSERT(0 <= insertion_index && insertion_index < new_size); | 5586 ASSERT(0 <= insertion_index && insertion_index < new_size); |
| 5581 | 5587 |
| 5582 PropertyDetails details = descriptors->GetDetails(insertion_index); | 5588 PropertyDetails details = descriptors->GetDetails(insertion_index); |
| 5583 ASSERT_LE(details.descriptor_index(), new_size); | 5589 ASSERT_LE(details.descriptor_index(), new_size); |
| (...skipping 1671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7255 | 7261 |
| 7256 Isolate* isolate = GetIsolate(); | 7262 Isolate* isolate = GetIsolate(); |
| 7257 StringComparator comparator(isolate->objects_string_compare_iterator_a(), | 7263 StringComparator comparator(isolate->objects_string_compare_iterator_a(), |
| 7258 isolate->objects_string_compare_iterator_b()); | 7264 isolate->objects_string_compare_iterator_b()); |
| 7259 | 7265 |
| 7260 return comparator.Equals(static_cast<unsigned>(len), lhs, rhs); | 7266 return comparator.Equals(static_cast<unsigned>(len), lhs, rhs); |
| 7261 } | 7267 } |
| 7262 | 7268 |
| 7263 | 7269 |
| 7264 bool String::MarkAsUndetectable() { | 7270 bool String::MarkAsUndetectable() { |
| 7265 if (StringShape(this).IsSymbol()) return false; | 7271 if (StringShape(this).IsInternalized()) return false; |
| 7266 | 7272 |
| 7267 Map* map = this->map(); | 7273 Map* map = this->map(); |
| 7268 Heap* heap = GetHeap(); | 7274 Heap* heap = GetHeap(); |
| 7269 if (map == heap->string_map()) { | 7275 if (map == heap->string_map()) { |
| 7270 this->set_map(heap->undetectable_string_map()); | 7276 this->set_map(heap->undetectable_string_map()); |
| 7271 return true; | 7277 return true; |
| 7272 } else if (map == heap->ascii_string_map()) { | 7278 } else if (map == heap->ascii_string_map()) { |
| 7273 this->set_map(heap->undetectable_ascii_string_map()); | 7279 this->set_map(heap->undetectable_ascii_string_map()); |
| 7274 return true; | 7280 return true; |
| 7275 } | 7281 } |
| (...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8079 | 8085 |
| 8080 | 8086 |
| 8081 Context* JSFunction::NativeContextFromLiterals(FixedArray* literals) { | 8087 Context* JSFunction::NativeContextFromLiterals(FixedArray* literals) { |
| 8082 return Context::cast(literals->get(JSFunction::kLiteralNativeContextIndex)); | 8088 return Context::cast(literals->get(JSFunction::kLiteralNativeContextIndex)); |
| 8083 } | 8089 } |
| 8084 | 8090 |
| 8085 | 8091 |
| 8086 MaybeObject* Oddball::Initialize(const char* to_string, | 8092 MaybeObject* Oddball::Initialize(const char* to_string, |
| 8087 Object* to_number, | 8093 Object* to_number, |
| 8088 byte kind) { | 8094 byte kind) { |
| 8089 String* symbol; | 8095 String* internalized_to_string; |
| 8090 { MaybeObject* maybe_symbol = | 8096 { MaybeObject* maybe_string = |
| 8091 Isolate::Current()->heap()->LookupUtf8Symbol(CStrVector(to_string)); | 8097 Isolate::Current()->heap()->InternalizeUtf8String( |
| 8092 if (!maybe_symbol->To(&symbol)) return maybe_symbol; | 8098 CStrVector(to_string)); |
| 8099 if (!maybe_string->To(&internalized_to_string)) return maybe_string; |
| 8093 } | 8100 } |
| 8094 set_to_string(symbol); | 8101 set_to_string(internalized_to_string); |
| 8095 set_to_number(to_number); | 8102 set_to_number(to_number); |
| 8096 set_kind(kind); | 8103 set_kind(kind); |
| 8097 return this; | 8104 return this; |
| 8098 } | 8105 } |
| 8099 | 8106 |
| 8100 | 8107 |
| 8101 String* SharedFunctionInfo::DebugName() { | 8108 String* SharedFunctionInfo::DebugName() { |
| 8102 Object* n = name(); | 8109 Object* n = name(); |
| 8103 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); | 8110 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); |
| 8104 return String::cast(n); | 8111 return String::cast(n); |
| (...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9411 Handle<Object> hresult; | 9418 Handle<Object> hresult; |
| 9412 if (!result->ToHandle(&hresult, isolate)) return result; | 9419 if (!result->ToHandle(&hresult, isolate)) return result; |
| 9413 | 9420 |
| 9414 CHECK(self->length()->ToArrayIndex(&new_length)); | 9421 CHECK(self->length()->ToArrayIndex(&new_length)); |
| 9415 if (old_length != new_length) { | 9422 if (old_length != new_length) { |
| 9416 for (int i = 0; i < indices.length(); ++i) { | 9423 for (int i = 0; i < indices.length(); ++i) { |
| 9417 JSObject::EnqueueChangeRecord( | 9424 JSObject::EnqueueChangeRecord( |
| 9418 self, "deleted", indices[i], old_values[i]); | 9425 self, "deleted", indices[i], old_values[i]); |
| 9419 } | 9426 } |
| 9420 JSObject::EnqueueChangeRecord( | 9427 JSObject::EnqueueChangeRecord( |
| 9421 self, "updated", isolate->factory()->length_symbol(), | 9428 self, "updated", isolate->factory()->length_string(), |
| 9422 old_length_handle); | 9429 old_length_handle); |
| 9423 } | 9430 } |
| 9424 return *hresult; | 9431 return *hresult; |
| 9425 } | 9432 } |
| 9426 | 9433 |
| 9427 | 9434 |
| 9428 Map* Map::GetPrototypeTransition(Object* prototype) { | 9435 Map* Map::GetPrototypeTransition(Object* prototype) { |
| 9429 FixedArray* cache = GetPrototypeTransitions(); | 9436 FixedArray* cache = GetPrototypeTransitions(); |
| 9430 int number_of_transitions = NumberOfProtoTransitions(); | 9437 int number_of_transitions = NumberOfProtoTransitions(); |
| 9431 const int proto_offset = | 9438 const int proto_offset = |
| (...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10369 Handle<Object> hresult; | 10376 Handle<Object> hresult; |
| 10370 if (!result->ToHandle(&hresult, isolate)) return result; | 10377 if (!result->ToHandle(&hresult, isolate)) return result; |
| 10371 | 10378 |
| 10372 Handle<String> name = isolate->factory()->Uint32ToString(index); | 10379 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 10373 PropertyAttributes new_attributes = self->GetLocalElementAttribute(index); | 10380 PropertyAttributes new_attributes = self->GetLocalElementAttribute(index); |
| 10374 if (old_attributes == ABSENT) { | 10381 if (old_attributes == ABSENT) { |
| 10375 EnqueueChangeRecord(self, "new", name, old_value); | 10382 EnqueueChangeRecord(self, "new", name, old_value); |
| 10376 if (self->IsJSArray() && | 10383 if (self->IsJSArray() && |
| 10377 !old_length->SameValue(Handle<JSArray>::cast(self)->length())) { | 10384 !old_length->SameValue(Handle<JSArray>::cast(self)->length())) { |
| 10378 EnqueueChangeRecord( | 10385 EnqueueChangeRecord( |
| 10379 self, "updated", isolate->factory()->length_symbol(), old_length); | 10386 self, "updated", isolate->factory()->length_string(), old_length); |
| 10380 } | 10387 } |
| 10381 } else if (old_value->IsTheHole()) { | 10388 } else if (old_value->IsTheHole()) { |
| 10382 EnqueueChangeRecord(self, "reconfigured", name, old_value); | 10389 EnqueueChangeRecord(self, "reconfigured", name, old_value); |
| 10383 } else { | 10390 } else { |
| 10384 bool value_changed = | 10391 bool value_changed = |
| 10385 !old_value->SameValue(*Object::GetElement(self, index)); | 10392 !old_value->SameValue(*Object::GetElement(self, index)); |
| 10386 if (old_attributes != new_attributes) { | 10393 if (old_attributes != new_attributes) { |
| 10387 if (!value_changed) old_value = isolate->factory()->the_hole_value(); | 10394 if (!value_changed) old_value = isolate->factory()->the_hole_value(); |
| 10388 EnqueueChangeRecord(self, "reconfigured", name, old_value); | 10395 EnqueueChangeRecord(self, "reconfigured", name, old_value); |
| 10389 } else if (value_changed) { | 10396 } else if (value_changed) { |
| (...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11541 } | 11548 } |
| 11542 | 11549 |
| 11543 static uint32_t RegExpHash(String* string, Smi* flags) { | 11550 static uint32_t RegExpHash(String* string, Smi* flags) { |
| 11544 return string->Hash() + flags->value(); | 11551 return string->Hash() + flags->value(); |
| 11545 } | 11552 } |
| 11546 | 11553 |
| 11547 String* string_; | 11554 String* string_; |
| 11548 Smi* flags_; | 11555 Smi* flags_; |
| 11549 }; | 11556 }; |
| 11550 | 11557 |
| 11551 // Utf8SymbolKey carries a vector of chars as key. | 11558 // Utf8StringKey carries a vector of chars as key. |
| 11552 class Utf8SymbolKey : public HashTableKey { | 11559 class Utf8StringKey : public HashTableKey { |
| 11553 public: | 11560 public: |
| 11554 explicit Utf8SymbolKey(Vector<const char> string, uint32_t seed) | 11561 explicit Utf8StringKey(Vector<const char> string, uint32_t seed) |
| 11555 : string_(string), hash_field_(0), seed_(seed) { } | 11562 : string_(string), hash_field_(0), seed_(seed) { } |
| 11556 | 11563 |
| 11557 bool IsMatch(Object* string) { | 11564 bool IsMatch(Object* string) { |
| 11558 return String::cast(string)->IsUtf8EqualTo(string_); | 11565 return String::cast(string)->IsUtf8EqualTo(string_); |
| 11559 } | 11566 } |
| 11560 | 11567 |
| 11561 uint32_t Hash() { | 11568 uint32_t Hash() { |
| 11562 if (hash_field_ != 0) return hash_field_ >> String::kHashShift; | 11569 if (hash_field_ != 0) return hash_field_ >> String::kHashShift; |
| 11563 hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_); | 11570 hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_); |
| 11564 uint32_t result = hash_field_ >> String::kHashShift; | 11571 uint32_t result = hash_field_ >> String::kHashShift; |
| 11565 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 11572 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
| 11566 return result; | 11573 return result; |
| 11567 } | 11574 } |
| 11568 | 11575 |
| 11569 uint32_t HashForObject(Object* other) { | 11576 uint32_t HashForObject(Object* other) { |
| 11570 return String::cast(other)->Hash(); | 11577 return String::cast(other)->Hash(); |
| 11571 } | 11578 } |
| 11572 | 11579 |
| 11573 MaybeObject* AsObject() { | 11580 MaybeObject* AsObject() { |
| 11574 if (hash_field_ == 0) Hash(); | 11581 if (hash_field_ == 0) Hash(); |
| 11575 return Isolate::Current()->heap()->AllocateSymbolFromUtf8( | 11582 return Isolate::Current()->heap()->AllocateInternalizedStringFromUtf8( |
| 11576 string_, chars_, hash_field_); | 11583 string_, chars_, hash_field_); |
| 11577 } | 11584 } |
| 11578 | 11585 |
| 11579 Vector<const char> string_; | 11586 Vector<const char> string_; |
| 11580 uint32_t hash_field_; | 11587 uint32_t hash_field_; |
| 11581 int chars_; // Caches the number of characters when computing the hash code. | 11588 int chars_; // Caches the number of characters when computing the hash code. |
| 11582 uint32_t seed_; | 11589 uint32_t seed_; |
| 11583 }; | 11590 }; |
| 11584 | 11591 |
| 11585 | 11592 |
| 11586 template <typename Char> | 11593 template <typename Char> |
| 11587 class SequentialSymbolKey : public HashTableKey { | 11594 class SequentialStringKey : public HashTableKey { |
| 11588 public: | 11595 public: |
| 11589 explicit SequentialSymbolKey(Vector<const Char> string, uint32_t seed) | 11596 explicit SequentialStringKey(Vector<const Char> string, uint32_t seed) |
| 11590 : string_(string), hash_field_(0), seed_(seed) { } | 11597 : string_(string), hash_field_(0), seed_(seed) { } |
| 11591 | 11598 |
| 11592 uint32_t Hash() { | 11599 uint32_t Hash() { |
| 11593 hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(), | 11600 hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(), |
| 11594 string_.length(), | 11601 string_.length(), |
| 11595 seed_); | 11602 seed_); |
| 11596 | 11603 |
| 11597 uint32_t result = hash_field_ >> String::kHashShift; | 11604 uint32_t result = hash_field_ >> String::kHashShift; |
| 11598 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 11605 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
| 11599 return result; | 11606 return result; |
| 11600 } | 11607 } |
| 11601 | 11608 |
| 11602 | 11609 |
| 11603 uint32_t HashForObject(Object* other) { | 11610 uint32_t HashForObject(Object* other) { |
| 11604 return String::cast(other)->Hash(); | 11611 return String::cast(other)->Hash(); |
| 11605 } | 11612 } |
| 11606 | 11613 |
| 11607 Vector<const Char> string_; | 11614 Vector<const Char> string_; |
| 11608 uint32_t hash_field_; | 11615 uint32_t hash_field_; |
| 11609 uint32_t seed_; | 11616 uint32_t seed_; |
| 11610 }; | 11617 }; |
| 11611 | 11618 |
| 11612 | 11619 |
| 11613 | 11620 |
| 11614 class OneByteSymbolKey : public SequentialSymbolKey<uint8_t> { | 11621 class OneByteStringKey : public SequentialStringKey<uint8_t> { |
| 11615 public: | 11622 public: |
| 11616 OneByteSymbolKey(Vector<const uint8_t> str, uint32_t seed) | 11623 OneByteStringKey(Vector<const uint8_t> str, uint32_t seed) |
| 11617 : SequentialSymbolKey<uint8_t>(str, seed) { } | 11624 : SequentialStringKey<uint8_t>(str, seed) { } |
| 11618 | 11625 |
| 11619 bool IsMatch(Object* string) { | 11626 bool IsMatch(Object* string) { |
| 11620 return String::cast(string)->IsOneByteEqualTo(string_); | 11627 return String::cast(string)->IsOneByteEqualTo(string_); |
| 11621 } | 11628 } |
| 11622 | 11629 |
| 11623 MaybeObject* AsObject() { | 11630 MaybeObject* AsObject() { |
| 11624 if (hash_field_ == 0) Hash(); | 11631 if (hash_field_ == 0) Hash(); |
| 11625 return HEAP->AllocateOneByteSymbol(string_, hash_field_); | 11632 return HEAP->AllocateOneByteInternalizedString(string_, hash_field_); |
| 11626 } | 11633 } |
| 11627 }; | 11634 }; |
| 11628 | 11635 |
| 11629 | 11636 |
| 11630 class SubStringOneByteSymbolKey : public HashTableKey { | 11637 class SubStringOneByteStringKey : public HashTableKey { |
| 11631 public: | 11638 public: |
| 11632 explicit SubStringOneByteSymbolKey(Handle<SeqOneByteString> string, | 11639 explicit SubStringOneByteStringKey(Handle<SeqOneByteString> string, |
| 11633 int from, | 11640 int from, |
| 11634 int length) | 11641 int length) |
| 11635 : string_(string), from_(from), length_(length) { } | 11642 : string_(string), from_(from), length_(length) { } |
| 11636 | 11643 |
| 11637 uint32_t Hash() { | 11644 uint32_t Hash() { |
| 11638 ASSERT(length_ >= 0); | 11645 ASSERT(length_ >= 0); |
| 11639 ASSERT(from_ + length_ <= string_->length()); | 11646 ASSERT(from_ + length_ <= string_->length()); |
| 11640 uint8_t* chars = string_->GetChars() + from_; | 11647 uint8_t* chars = string_->GetChars() + from_; |
| 11641 hash_field_ = StringHasher::HashSequentialString( | 11648 hash_field_ = StringHasher::HashSequentialString( |
| 11642 chars, length_, string_->GetHeap()->HashSeed()); | 11649 chars, length_, string_->GetHeap()->HashSeed()); |
| 11643 uint32_t result = hash_field_ >> String::kHashShift; | 11650 uint32_t result = hash_field_ >> String::kHashShift; |
| 11644 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 11651 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
| 11645 return result; | 11652 return result; |
| 11646 } | 11653 } |
| 11647 | 11654 |
| 11648 | 11655 |
| 11649 uint32_t HashForObject(Object* other) { | 11656 uint32_t HashForObject(Object* other) { |
| 11650 return String::cast(other)->Hash(); | 11657 return String::cast(other)->Hash(); |
| 11651 } | 11658 } |
| 11652 | 11659 |
| 11653 bool IsMatch(Object* string) { | 11660 bool IsMatch(Object* string) { |
| 11654 Vector<const uint8_t> chars(string_->GetChars() + from_, length_); | 11661 Vector<const uint8_t> chars(string_->GetChars() + from_, length_); |
| 11655 return String::cast(string)->IsOneByteEqualTo(chars); | 11662 return String::cast(string)->IsOneByteEqualTo(chars); |
| 11656 } | 11663 } |
| 11657 | 11664 |
| 11658 MaybeObject* AsObject() { | 11665 MaybeObject* AsObject() { |
| 11659 if (hash_field_ == 0) Hash(); | 11666 if (hash_field_ == 0) Hash(); |
| 11660 Vector<const uint8_t> chars(string_->GetChars() + from_, length_); | 11667 Vector<const uint8_t> chars(string_->GetChars() + from_, length_); |
| 11661 return HEAP->AllocateOneByteSymbol(chars, hash_field_); | 11668 return HEAP->AllocateOneByteInternalizedString(chars, hash_field_); |
| 11662 } | 11669 } |
| 11663 | 11670 |
| 11664 private: | 11671 private: |
| 11665 Handle<SeqOneByteString> string_; | 11672 Handle<SeqOneByteString> string_; |
| 11666 int from_; | 11673 int from_; |
| 11667 int length_; | 11674 int length_; |
| 11668 uint32_t hash_field_; | 11675 uint32_t hash_field_; |
| 11669 }; | 11676 }; |
| 11670 | 11677 |
| 11671 | 11678 |
| 11672 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { | 11679 class TwoByteStringKey : public SequentialStringKey<uc16> { |
| 11673 public: | 11680 public: |
| 11674 explicit TwoByteSymbolKey(Vector<const uc16> str, uint32_t seed) | 11681 explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed) |
| 11675 : SequentialSymbolKey<uc16>(str, seed) { } | 11682 : SequentialStringKey<uc16>(str, seed) { } |
| 11676 | 11683 |
| 11677 bool IsMatch(Object* string) { | 11684 bool IsMatch(Object* string) { |
| 11678 return String::cast(string)->IsTwoByteEqualTo(string_); | 11685 return String::cast(string)->IsTwoByteEqualTo(string_); |
| 11679 } | 11686 } |
| 11680 | 11687 |
| 11681 MaybeObject* AsObject() { | 11688 MaybeObject* AsObject() { |
| 11682 if (hash_field_ == 0) Hash(); | 11689 if (hash_field_ == 0) Hash(); |
| 11683 return HEAP->AllocateTwoByteSymbol(string_, hash_field_); | 11690 return HEAP->AllocateTwoByteInternalizedString(string_, hash_field_); |
| 11684 } | 11691 } |
| 11685 }; | 11692 }; |
| 11686 | 11693 |
| 11687 | 11694 |
| 11688 // SymbolKey carries a string/symbol object as key. | 11695 // InternalizedStringKey carries a string/internalized-string object as key. |
| 11689 class SymbolKey : public HashTableKey { | 11696 class InternalizedStringKey : public HashTableKey { |
| 11690 public: | 11697 public: |
| 11691 explicit SymbolKey(String* string) | 11698 explicit InternalizedStringKey(String* string) |
| 11692 : string_(string) { } | 11699 : string_(string) { } |
| 11693 | 11700 |
| 11694 bool IsMatch(Object* string) { | 11701 bool IsMatch(Object* string) { |
| 11695 return String::cast(string)->Equals(string_); | 11702 return String::cast(string)->Equals(string_); |
| 11696 } | 11703 } |
| 11697 | 11704 |
| 11698 uint32_t Hash() { return string_->Hash(); } | 11705 uint32_t Hash() { return string_->Hash(); } |
| 11699 | 11706 |
| 11700 uint32_t HashForObject(Object* other) { | 11707 uint32_t HashForObject(Object* other) { |
| 11701 return String::cast(other)->Hash(); | 11708 return String::cast(other)->Hash(); |
| 11702 } | 11709 } |
| 11703 | 11710 |
| 11704 MaybeObject* AsObject() { | 11711 MaybeObject* AsObject() { |
| 11705 // Attempt to flatten the string, so that symbols will most often | 11712 // Attempt to flatten the string, so that internalized strings will most |
| 11706 // be flat strings. | 11713 // often be flat strings. |
| 11707 string_ = string_->TryFlattenGetString(); | 11714 string_ = string_->TryFlattenGetString(); |
| 11708 Heap* heap = string_->GetHeap(); | 11715 Heap* heap = string_->GetHeap(); |
| 11709 // Transform string to symbol if possible. | 11716 // Internalize the string if possible. |
| 11710 Map* map = heap->SymbolMapForString(string_); | 11717 Map* map = heap->InternalizedStringMapForString(string_); |
| 11711 if (map != NULL) { | 11718 if (map != NULL) { |
| 11712 string_->set_map_no_write_barrier(map); | 11719 string_->set_map_no_write_barrier(map); |
| 11713 ASSERT(string_->IsSymbol()); | 11720 ASSERT(string_->IsInternalizedString()); |
| 11714 return string_; | 11721 return string_; |
| 11715 } | 11722 } |
| 11716 // Otherwise allocate a new symbol. | 11723 // Otherwise allocate a new internalized string. |
| 11717 return heap->AllocateInternalSymbol(string_, | 11724 return heap->AllocateInternalizedStringImpl( |
| 11718 string_->length(), | 11725 string_, string_->length(), string_->hash_field()); |
| 11719 string_->hash_field()); | |
| 11720 } | 11726 } |
| 11721 | 11727 |
| 11722 static uint32_t StringHash(Object* obj) { | 11728 static uint32_t StringHash(Object* obj) { |
| 11723 return String::cast(obj)->Hash(); | 11729 return String::cast(obj)->Hash(); |
| 11724 } | 11730 } |
| 11725 | 11731 |
| 11726 String* string_; | 11732 String* string_; |
| 11727 }; | 11733 }; |
| 11728 | 11734 |
| 11729 | 11735 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 11760 } | 11766 } |
| 11761 HashTable::cast(obj)->SetNumberOfElements(0); | 11767 HashTable::cast(obj)->SetNumberOfElements(0); |
| 11762 HashTable::cast(obj)->SetNumberOfDeletedElements(0); | 11768 HashTable::cast(obj)->SetNumberOfDeletedElements(0); |
| 11763 HashTable::cast(obj)->SetCapacity(capacity); | 11769 HashTable::cast(obj)->SetCapacity(capacity); |
| 11764 return obj; | 11770 return obj; |
| 11765 } | 11771 } |
| 11766 | 11772 |
| 11767 | 11773 |
| 11768 // Find entry for key otherwise return kNotFound. | 11774 // Find entry for key otherwise return kNotFound. |
| 11769 int StringDictionary::FindEntry(String* key) { | 11775 int StringDictionary::FindEntry(String* key) { |
| 11770 if (!key->IsSymbol()) { | 11776 if (!key->IsInternalizedString()) { |
| 11771 return HashTable<StringDictionaryShape, String*>::FindEntry(key); | 11777 return HashTable<StringDictionaryShape, String*>::FindEntry(key); |
| 11772 } | 11778 } |
| 11773 | 11779 |
| 11774 // Optimized for symbol key. Knowledge of the key type allows: | 11780 // Optimized for internalized string key. Knowledge of the key type allows: |
| 11775 // 1. Move the check if the key is a symbol out of the loop. | 11781 // 1. Move the check if the key is internalized out of the loop. |
| 11776 // 2. Avoid comparing hash codes in symbol to symbol comparison. | 11782 // 2. Avoid comparing hash codes in internalized-to-internalized comparison. |
| 11777 // 3. Detect a case when a dictionary key is not a symbol but the key is. | 11783 // 3. Detect a case when a dictionary key is not internalized but the key is. |
| 11778 // In case of positive result the dictionary key may be replaced by | 11784 // In case of positive result the dictionary key may be replaced by the |
| 11779 // the symbol with minimal performance penalty. It gives a chance to | 11785 // internalized string with minimal performance penalty. It gives a chance |
| 11780 // perform further lookups in code stubs (and significant performance boost | 11786 // to perform further lookups in code stubs (and significant performance |
| 11781 // a certain style of code). | 11787 // boost a certain style of code). |
| 11782 | 11788 |
| 11783 // EnsureCapacity will guarantee the hash table is never full. | 11789 // EnsureCapacity will guarantee the hash table is never full. |
| 11784 uint32_t capacity = Capacity(); | 11790 uint32_t capacity = Capacity(); |
| 11785 uint32_t entry = FirstProbe(key->Hash(), capacity); | 11791 uint32_t entry = FirstProbe(key->Hash(), capacity); |
| 11786 uint32_t count = 1; | 11792 uint32_t count = 1; |
| 11787 | 11793 |
| 11788 while (true) { | 11794 while (true) { |
| 11789 int index = EntryToIndex(entry); | 11795 int index = EntryToIndex(entry); |
| 11790 Object* element = get(index); | 11796 Object* element = get(index); |
| 11791 if (element->IsUndefined()) break; // Empty entry. | 11797 if (element->IsUndefined()) break; // Empty entry. |
| 11792 if (key == element) return entry; | 11798 if (key == element) return entry; |
| 11793 if (!element->IsSymbol() && | 11799 if (!element->IsInternalizedString() && |
| 11794 !element->IsTheHole() && | 11800 !element->IsTheHole() && |
| 11795 String::cast(element)->Equals(key)) { | 11801 String::cast(element)->Equals(key)) { |
| 11796 // Replace a non-symbol key by the equivalent symbol for faster further | 11802 // Replace a key that is not an internalized string by the equivalent |
| 11797 // lookups. | 11803 // internalized string for faster further lookups. |
| 11798 set(index, key); | 11804 set(index, key); |
| 11799 return entry; | 11805 return entry; |
| 11800 } | 11806 } |
| 11801 ASSERT(element->IsTheHole() || !String::cast(element)->Equals(key)); | 11807 ASSERT(element->IsTheHole() || !String::cast(element)->Equals(key)); |
| 11802 entry = NextProbe(entry, count++, capacity); | 11808 entry = NextProbe(entry, count++, capacity); |
| 11803 } | 11809 } |
| 11804 return kNotFound; | 11810 return kNotFound; |
| 11805 } | 11811 } |
| 11806 | 11812 |
| 11807 | 11813 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11908 Object* element = KeyAt(entry); | 11914 Object* element = KeyAt(entry); |
| 11909 if (element->IsUndefined() || element->IsTheHole()) break; | 11915 if (element->IsUndefined() || element->IsTheHole()) break; |
| 11910 entry = NextProbe(entry, count++, capacity); | 11916 entry = NextProbe(entry, count++, capacity); |
| 11911 } | 11917 } |
| 11912 return entry; | 11918 return entry; |
| 11913 } | 11919 } |
| 11914 | 11920 |
| 11915 // Force instantiation of template instances class. | 11921 // Force instantiation of template instances class. |
| 11916 // Please note this list is compiler dependent. | 11922 // Please note this list is compiler dependent. |
| 11917 | 11923 |
| 11918 template class HashTable<SymbolTableShape, HashTableKey*>; | 11924 template class HashTable<StringTableShape, HashTableKey*>; |
| 11919 | 11925 |
| 11920 template class HashTable<CompilationCacheShape, HashTableKey*>; | 11926 template class HashTable<CompilationCacheShape, HashTableKey*>; |
| 11921 | 11927 |
| 11922 template class HashTable<MapCacheShape, HashTableKey*>; | 11928 template class HashTable<MapCacheShape, HashTableKey*>; |
| 11923 | 11929 |
| 11924 template class HashTable<ObjectHashTableShape<1>, Object*>; | 11930 template class HashTable<ObjectHashTableShape<1>, Object*>; |
| 11925 | 11931 |
| 11926 template class HashTable<ObjectHashTableShape<2>, Object*>; | 11932 template class HashTable<ObjectHashTableShape<2>, Object*>; |
| 11927 | 11933 |
| 11928 template class Dictionary<StringDictionaryShape, String*>; | 11934 template class Dictionary<StringDictionaryShape, String*>; |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12465 set_properties(StringDictionary::cast(dictionary)); | 12471 set_properties(StringDictionary::cast(dictionary)); |
| 12466 return cell; | 12472 return cell; |
| 12467 } else { | 12473 } else { |
| 12468 Object* value = property_dictionary()->ValueAt(entry); | 12474 Object* value = property_dictionary()->ValueAt(entry); |
| 12469 ASSERT(value->IsJSGlobalPropertyCell()); | 12475 ASSERT(value->IsJSGlobalPropertyCell()); |
| 12470 return value; | 12476 return value; |
| 12471 } | 12477 } |
| 12472 } | 12478 } |
| 12473 | 12479 |
| 12474 | 12480 |
| 12475 MaybeObject* SymbolTable::LookupString(String* string, Object** s) { | 12481 MaybeObject* StringTable::LookupString(String* string, Object** s) { |
| 12476 SymbolKey key(string); | 12482 InternalizedStringKey key(string); |
| 12477 return LookupKey(&key, s); | 12483 return LookupKey(&key, s); |
| 12478 } | 12484 } |
| 12479 | 12485 |
| 12480 | 12486 |
| 12481 // This class is used for looking up two character strings in the symbol table. | 12487 // This class is used for looking up two character strings in the string table. |
| 12482 // If we don't have a hit we don't want to waste much time so we unroll the | 12488 // If we don't have a hit we don't want to waste much time so we unroll the |
| 12483 // string hash calculation loop here for speed. Doesn't work if the two | 12489 // string hash calculation loop here for speed. Doesn't work if the two |
| 12484 // characters form a decimal integer, since such strings have a different hash | 12490 // characters form a decimal integer, since such strings have a different hash |
| 12485 // algorithm. | 12491 // algorithm. |
| 12486 class TwoCharHashTableKey : public HashTableKey { | 12492 class TwoCharHashTableKey : public HashTableKey { |
| 12487 public: | 12493 public: |
| 12488 TwoCharHashTableKey(uint16_t c1, uint16_t c2, uint32_t seed) | 12494 TwoCharHashTableKey(uint16_t c1, uint16_t c2, uint32_t seed) |
| 12489 : c1_(c1), c2_(c2) { | 12495 : c1_(c1), c2_(c2) { |
| 12490 // Char 1. | 12496 // Char 1. |
| 12491 uint32_t hash = seed; | 12497 uint32_t hash = seed; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 12522 return other->Get(1) == c2_; | 12528 return other->Get(1) == c2_; |
| 12523 } | 12529 } |
| 12524 | 12530 |
| 12525 uint32_t Hash() { return hash_; } | 12531 uint32_t Hash() { return hash_; } |
| 12526 uint32_t HashForObject(Object* key) { | 12532 uint32_t HashForObject(Object* key) { |
| 12527 if (!key->IsString()) return 0; | 12533 if (!key->IsString()) return 0; |
| 12528 return String::cast(key)->Hash(); | 12534 return String::cast(key)->Hash(); |
| 12529 } | 12535 } |
| 12530 | 12536 |
| 12531 Object* AsObject() { | 12537 Object* AsObject() { |
| 12532 // The TwoCharHashTableKey is only used for looking in the symbol | 12538 // The TwoCharHashTableKey is only used for looking in the string |
| 12533 // table, not for adding to it. | 12539 // table, not for adding to it. |
| 12534 UNREACHABLE(); | 12540 UNREACHABLE(); |
| 12535 return NULL; | 12541 return NULL; |
| 12536 } | 12542 } |
| 12537 | 12543 |
| 12538 private: | 12544 private: |
| 12539 uint16_t c1_; | 12545 uint16_t c1_; |
| 12540 uint16_t c2_; | 12546 uint16_t c2_; |
| 12541 uint32_t hash_; | 12547 uint32_t hash_; |
| 12542 }; | 12548 }; |
| 12543 | 12549 |
| 12544 | 12550 |
| 12545 bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) { | 12551 bool StringTable::LookupStringIfExists(String* string, String** result) { |
| 12546 SymbolKey key(string); | 12552 InternalizedStringKey key(string); |
| 12547 int entry = FindEntry(&key); | 12553 int entry = FindEntry(&key); |
| 12548 if (entry == kNotFound) { | 12554 if (entry == kNotFound) { |
| 12549 return false; | 12555 return false; |
| 12550 } else { | 12556 } else { |
| 12551 String* result = String::cast(KeyAt(entry)); | 12557 *result = String::cast(KeyAt(entry)); |
| 12552 ASSERT(StringShape(result).IsSymbol()); | 12558 ASSERT(StringShape(*result).IsInternalized()); |
| 12553 *symbol = result; | |
| 12554 return true; | 12559 return true; |
| 12555 } | 12560 } |
| 12556 } | 12561 } |
| 12557 | 12562 |
| 12558 | 12563 |
| 12559 bool SymbolTable::LookupTwoCharsSymbolIfExists(uint16_t c1, | 12564 bool StringTable::LookupTwoCharsStringIfExists(uint16_t c1, |
| 12560 uint16_t c2, | 12565 uint16_t c2, |
| 12561 String** symbol) { | 12566 String** result) { |
| 12562 TwoCharHashTableKey key(c1, c2, GetHeap()->HashSeed()); | 12567 TwoCharHashTableKey key(c1, c2, GetHeap()->HashSeed()); |
| 12563 int entry = FindEntry(&key); | 12568 int entry = FindEntry(&key); |
| 12564 if (entry == kNotFound) { | 12569 if (entry == kNotFound) { |
| 12565 return false; | 12570 return false; |
| 12566 } else { | 12571 } else { |
| 12567 String* result = String::cast(KeyAt(entry)); | 12572 *result = String::cast(KeyAt(entry)); |
| 12568 ASSERT(StringShape(result).IsSymbol()); | 12573 ASSERT(StringShape(*result).IsInternalized()); |
| 12569 *symbol = result; | |
| 12570 return true; | 12574 return true; |
| 12571 } | 12575 } |
| 12572 } | 12576 } |
| 12573 | 12577 |
| 12574 | 12578 |
| 12575 MaybeObject* SymbolTable::LookupUtf8Symbol(Vector<const char> str, | 12579 MaybeObject* StringTable::LookupUtf8String(Vector<const char> str, |
| 12576 Object** s) { | 12580 Object** s) { |
| 12577 Utf8SymbolKey key(str, GetHeap()->HashSeed()); | 12581 Utf8StringKey key(str, GetHeap()->HashSeed()); |
| 12578 return LookupKey(&key, s); | 12582 return LookupKey(&key, s); |
| 12579 } | 12583 } |
| 12580 | 12584 |
| 12581 | 12585 |
| 12582 MaybeObject* SymbolTable::LookupOneByteSymbol(Vector<const uint8_t> str, | 12586 MaybeObject* StringTable::LookupOneByteString(Vector<const uint8_t> str, |
| 12583 Object** s) { | 12587 Object** s) { |
| 12584 OneByteSymbolKey key(str, GetHeap()->HashSeed()); | 12588 OneByteStringKey key(str, GetHeap()->HashSeed()); |
| 12585 return LookupKey(&key, s); | 12589 return LookupKey(&key, s); |
| 12586 } | 12590 } |
| 12587 | 12591 |
| 12588 | 12592 |
| 12589 MaybeObject* SymbolTable::LookupSubStringOneByteSymbol( | 12593 MaybeObject* StringTable::LookupSubStringOneByteString( |
| 12590 Handle<SeqOneByteString> str, | 12594 Handle<SeqOneByteString> str, |
| 12591 int from, | 12595 int from, |
| 12592 int length, | 12596 int length, |
| 12593 Object** s) { | 12597 Object** s) { |
| 12594 SubStringOneByteSymbolKey key(str, from, length); | 12598 SubStringOneByteStringKey key(str, from, length); |
| 12595 return LookupKey(&key, s); | 12599 return LookupKey(&key, s); |
| 12596 } | 12600 } |
| 12597 | 12601 |
| 12598 | 12602 |
| 12599 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, | 12603 MaybeObject* StringTable::LookupTwoByteString(Vector<const uc16> str, |
| 12600 Object** s) { | 12604 Object** s) { |
| 12601 TwoByteSymbolKey key(str, GetHeap()->HashSeed()); | 12605 TwoByteStringKey key(str, GetHeap()->HashSeed()); |
| 12602 return LookupKey(&key, s); | 12606 return LookupKey(&key, s); |
| 12603 } | 12607 } |
| 12604 | 12608 |
| 12605 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { | 12609 MaybeObject* StringTable::LookupKey(HashTableKey* key, Object** s) { |
| 12606 int entry = FindEntry(key); | 12610 int entry = FindEntry(key); |
| 12607 | 12611 |
| 12608 // Symbol already in table. | 12612 // String already in table. |
| 12609 if (entry != kNotFound) { | 12613 if (entry != kNotFound) { |
| 12610 *s = KeyAt(entry); | 12614 *s = KeyAt(entry); |
| 12611 return this; | 12615 return this; |
| 12612 } | 12616 } |
| 12613 | 12617 |
| 12614 // Adding new symbol. Grow table if needed. | 12618 // Adding new string. Grow table if needed. |
| 12615 Object* obj; | 12619 Object* obj; |
| 12616 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 12620 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 12617 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 12621 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 12618 } | 12622 } |
| 12619 | 12623 |
| 12620 // Create symbol object. | 12624 // Create string object. |
| 12621 Object* symbol; | 12625 Object* string; |
| 12622 { MaybeObject* maybe_symbol = key->AsObject(); | 12626 { MaybeObject* maybe_string = key->AsObject(); |
| 12623 if (!maybe_symbol->ToObject(&symbol)) return maybe_symbol; | 12627 if (!maybe_string->ToObject(&string)) return maybe_string; |
| 12624 } | 12628 } |
| 12625 | 12629 |
| 12626 // If the symbol table grew as part of EnsureCapacity, obj is not | 12630 // If the string table grew as part of EnsureCapacity, obj is not |
| 12627 // the current symbol table and therefore we cannot use | 12631 // the current string table and therefore we cannot use |
| 12628 // SymbolTable::cast here. | 12632 // StringTable::cast here. |
| 12629 SymbolTable* table = reinterpret_cast<SymbolTable*>(obj); | 12633 StringTable* table = reinterpret_cast<StringTable*>(obj); |
| 12630 | 12634 |
| 12631 // Add the new symbol and return it along with the symbol table. | 12635 // Add the new string and return it along with the string table. |
| 12632 entry = table->FindInsertionEntry(key->Hash()); | 12636 entry = table->FindInsertionEntry(key->Hash()); |
| 12633 table->set(EntryToIndex(entry), symbol); | 12637 table->set(EntryToIndex(entry), string); |
| 12634 table->ElementAdded(); | 12638 table->ElementAdded(); |
| 12635 *s = symbol; | 12639 *s = string; |
| 12636 return table; | 12640 return table; |
| 12637 } | 12641 } |
| 12638 | 12642 |
| 12639 | 12643 |
| 12640 // The key for the script compilation cache is dependent on the mode flags, | 12644 // The key for the script compilation cache is dependent on the mode flags, |
| 12641 // because they change the global language mode and thus binding behaviour. | 12645 // because they change the global language mode and thus binding behaviour. |
| 12642 // If flags change at some point, we must ensure that we do not hit the cache | 12646 // If flags change at some point, we must ensure that we do not hit the cache |
| 12643 // for code compiled with different settings. | 12647 // for code compiled with different settings. |
| 12644 static LanguageMode CurrentGlobalLanguageMode() { | 12648 static LanguageMode CurrentGlobalLanguageMode() { |
| 12645 return FLAG_use_strict | 12649 return FLAG_use_strict |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12765 if (get(value_index) == value) { | 12769 if (get(value_index) == value) { |
| 12766 NoWriteBarrierSet(this, entry_index, the_hole_value); | 12770 NoWriteBarrierSet(this, entry_index, the_hole_value); |
| 12767 NoWriteBarrierSet(this, value_index, the_hole_value); | 12771 NoWriteBarrierSet(this, value_index, the_hole_value); |
| 12768 ElementRemoved(); | 12772 ElementRemoved(); |
| 12769 } | 12773 } |
| 12770 } | 12774 } |
| 12771 return; | 12775 return; |
| 12772 } | 12776 } |
| 12773 | 12777 |
| 12774 | 12778 |
| 12775 // SymbolsKey used for HashTable where key is array of symbols. | 12779 // StringsKey used for HashTable where key is array of internalzied strings. |
| 12776 class SymbolsKey : public HashTableKey { | 12780 class StringsKey : public HashTableKey { |
| 12777 public: | 12781 public: |
| 12778 explicit SymbolsKey(FixedArray* symbols) : symbols_(symbols) { } | 12782 explicit StringsKey(FixedArray* strings) : strings_(strings) { } |
| 12779 | 12783 |
| 12780 bool IsMatch(Object* symbols) { | 12784 bool IsMatch(Object* strings) { |
| 12781 FixedArray* o = FixedArray::cast(symbols); | 12785 FixedArray* o = FixedArray::cast(strings); |
| 12782 int len = symbols_->length(); | 12786 int len = strings_->length(); |
| 12783 if (o->length() != len) return false; | 12787 if (o->length() != len) return false; |
| 12784 for (int i = 0; i < len; i++) { | 12788 for (int i = 0; i < len; i++) { |
| 12785 if (o->get(i) != symbols_->get(i)) return false; | 12789 if (o->get(i) != strings_->get(i)) return false; |
| 12786 } | 12790 } |
| 12787 return true; | 12791 return true; |
| 12788 } | 12792 } |
| 12789 | 12793 |
| 12790 uint32_t Hash() { return HashForObject(symbols_); } | 12794 uint32_t Hash() { return HashForObject(strings_); } |
| 12791 | 12795 |
| 12792 uint32_t HashForObject(Object* obj) { | 12796 uint32_t HashForObject(Object* obj) { |
| 12793 FixedArray* symbols = FixedArray::cast(obj); | 12797 FixedArray* strings = FixedArray::cast(obj); |
| 12794 int len = symbols->length(); | 12798 int len = strings->length(); |
| 12795 uint32_t hash = 0; | 12799 uint32_t hash = 0; |
| 12796 for (int i = 0; i < len; i++) { | 12800 for (int i = 0; i < len; i++) { |
| 12797 hash ^= String::cast(symbols->get(i))->Hash(); | 12801 hash ^= String::cast(strings->get(i))->Hash(); |
| 12798 } | 12802 } |
| 12799 return hash; | 12803 return hash; |
| 12800 } | 12804 } |
| 12801 | 12805 |
| 12802 Object* AsObject() { return symbols_; } | 12806 Object* AsObject() { return strings_; } |
| 12803 | 12807 |
| 12804 private: | 12808 private: |
| 12805 FixedArray* symbols_; | 12809 FixedArray* strings_; |
| 12806 }; | 12810 }; |
| 12807 | 12811 |
| 12808 | 12812 |
| 12809 Object* MapCache::Lookup(FixedArray* array) { | 12813 Object* MapCache::Lookup(FixedArray* array) { |
| 12810 SymbolsKey key(array); | 12814 StringsKey key(array); |
| 12811 int entry = FindEntry(&key); | 12815 int entry = FindEntry(&key); |
| 12812 if (entry == kNotFound) return GetHeap()->undefined_value(); | 12816 if (entry == kNotFound) return GetHeap()->undefined_value(); |
| 12813 return get(EntryToIndex(entry) + 1); | 12817 return get(EntryToIndex(entry) + 1); |
| 12814 } | 12818 } |
| 12815 | 12819 |
| 12816 | 12820 |
| 12817 MaybeObject* MapCache::Put(FixedArray* array, Map* value) { | 12821 MaybeObject* MapCache::Put(FixedArray* array, Map* value) { |
| 12818 SymbolsKey key(array); | 12822 StringsKey key(array); |
| 12819 Object* obj; | 12823 Object* obj; |
| 12820 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 12824 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 12821 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 12825 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 12822 } | 12826 } |
| 12823 | 12827 |
| 12824 MapCache* cache = reinterpret_cast<MapCache*>(obj); | 12828 MapCache* cache = reinterpret_cast<MapCache*>(obj); |
| 12825 int entry = cache->FindInsertionEntry(key.Hash()); | 12829 int entry = cache->FindInsertionEntry(key.Hash()); |
| 12826 cache->set(EntryToIndex(entry), array); | 12830 cache->set(EntryToIndex(entry), array); |
| 12827 cache->set(EntryToIndex(entry) + 1, value); | 12831 cache->set(EntryToIndex(entry) + 1, value); |
| 12828 cache->ElementAdded(); | 12832 cache->ElementAdded(); |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13327 MaybeObject* maybe_fields = | 13331 MaybeObject* maybe_fields = |
| 13328 heap->AllocateFixedArray(number_of_allocated_fields); | 13332 heap->AllocateFixedArray(number_of_allocated_fields); |
| 13329 if (!maybe_fields->To(&fields)) return maybe_fields; | 13333 if (!maybe_fields->To(&fields)) return maybe_fields; |
| 13330 | 13334 |
| 13331 // Fill in the instance descriptor and the fields. | 13335 // Fill in the instance descriptor and the fields. |
| 13332 int current_offset = 0; | 13336 int current_offset = 0; |
| 13333 for (int i = 0; i < capacity; i++) { | 13337 for (int i = 0; i < capacity; i++) { |
| 13334 Object* k = KeyAt(i); | 13338 Object* k = KeyAt(i); |
| 13335 if (IsKey(k)) { | 13339 if (IsKey(k)) { |
| 13336 Object* value = ValueAt(i); | 13340 Object* value = ValueAt(i); |
| 13337 // Ensure the key is a symbol before writing into the instance descriptor. | 13341 // Ensure the key is an internalized string before writing into the |
| 13342 // instance descriptor. |
| 13338 String* key; | 13343 String* key; |
| 13339 MaybeObject* maybe_key = heap->LookupSymbol(String::cast(k)); | 13344 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); |
| 13340 if (!maybe_key->To(&key)) return maybe_key; | 13345 if (!maybe_key->To(&key)) return maybe_key; |
| 13341 | 13346 |
| 13342 PropertyDetails details = DetailsAt(i); | 13347 PropertyDetails details = DetailsAt(i); |
| 13343 ASSERT(details.descriptor_index() == details.dictionary_index()); | 13348 ASSERT(details.descriptor_index() == details.dictionary_index()); |
| 13344 int enumeration_index = details.descriptor_index(); | 13349 int enumeration_index = details.descriptor_index(); |
| 13345 PropertyType type = details.type(); | 13350 PropertyType type = details.type(); |
| 13346 | 13351 |
| 13347 if (value->IsJSFunction()) { | 13352 if (value->IsJSFunction()) { |
| 13348 ConstantFunctionDescriptor d(key, | 13353 ConstantFunctionDescriptor d(key, |
| 13349 JSFunction::cast(value), | 13354 JSFunction::cast(value), |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13892 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13897 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 13893 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13898 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 13894 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13899 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 13895 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13900 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 13896 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13901 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 13897 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13902 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 13898 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13903 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 13899 } | 13904 } |
| 13900 | 13905 |
| 13901 } } // namespace v8::internal | 13906 } } // namespace v8::internal |
| OLD | NEW |