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 |