Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: src/objects.cc

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 962 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 accumulator->Add("<ExternalUnsignedIntArray[%u]>", 973 accumulator->Add("<ExternalUnsignedIntArray[%u]>",
974 ExternalUnsignedIntArray::cast(this)->length()); 974 ExternalUnsignedIntArray::cast(this)->length());
975 break; 975 break;
976 case EXTERNAL_FLOAT_ARRAY_TYPE: 976 case EXTERNAL_FLOAT_ARRAY_TYPE:
977 accumulator->Add("<ExternalFloatArray[%u]>", 977 accumulator->Add("<ExternalFloatArray[%u]>",
978 ExternalFloatArray::cast(this)->length()); 978 ExternalFloatArray::cast(this)->length());
979 break; 979 break;
980 case SHARED_FUNCTION_INFO_TYPE: 980 case SHARED_FUNCTION_INFO_TYPE:
981 accumulator->Add("<SharedFunctionInfo>"); 981 accumulator->Add("<SharedFunctionInfo>");
982 break; 982 break;
983 case JS_MESSAGE_OBJECT_TYPE:
984 accumulator->Add("<JSMessageObject>");
985 break;
983 #define MAKE_STRUCT_CASE(NAME, Name, name) \ 986 #define MAKE_STRUCT_CASE(NAME, Name, name) \
984 case NAME##_TYPE: \ 987 case NAME##_TYPE: \
985 accumulator->Put('<'); \ 988 accumulator->Put('<'); \
986 accumulator->Add(#Name); \ 989 accumulator->Add(#Name); \
987 accumulator->Put('>'); \ 990 accumulator->Put('>'); \
988 break; 991 break;
989 STRUCT_LIST(MAKE_STRUCT_CASE) 992 STRUCT_LIST(MAKE_STRUCT_CASE)
990 #undef MAKE_STRUCT_CASE 993 #undef MAKE_STRUCT_CASE
991 case CODE_TYPE: 994 case CODE_TYPE:
992 accumulator->Add("<Code>"); 995 accumulator->Add("<Code>");
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); 1066 FixedArray::BodyDescriptor::IterateBody(this, object_size, v);
1064 break; 1067 break;
1065 case JS_OBJECT_TYPE: 1068 case JS_OBJECT_TYPE:
1066 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 1069 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
1067 case JS_VALUE_TYPE: 1070 case JS_VALUE_TYPE:
1068 case JS_ARRAY_TYPE: 1071 case JS_ARRAY_TYPE:
1069 case JS_REGEXP_TYPE: 1072 case JS_REGEXP_TYPE:
1070 case JS_GLOBAL_PROXY_TYPE: 1073 case JS_GLOBAL_PROXY_TYPE:
1071 case JS_GLOBAL_OBJECT_TYPE: 1074 case JS_GLOBAL_OBJECT_TYPE:
1072 case JS_BUILTINS_OBJECT_TYPE: 1075 case JS_BUILTINS_OBJECT_TYPE:
1076 case JS_MESSAGE_OBJECT_TYPE:
1073 JSObject::BodyDescriptor::IterateBody(this, object_size, v); 1077 JSObject::BodyDescriptor::IterateBody(this, object_size, v);
1074 break; 1078 break;
1075 case JS_FUNCTION_TYPE: 1079 case JS_FUNCTION_TYPE:
1076 reinterpret_cast<JSFunction*>(this) 1080 reinterpret_cast<JSFunction*>(this)
1077 ->JSFunctionIterateBody(object_size, v); 1081 ->JSFunctionIterateBody(object_size, v);
1078 break; 1082 break;
1079 case ODDBALL_TYPE: 1083 case ODDBALL_TYPE:
1080 Oddball::BodyDescriptor::IterateBody(this, v); 1084 Oddball::BodyDescriptor::IterateBody(this, v);
1081 break; 1085 break;
1082 case PROXY_TYPE: 1086 case PROXY_TYPE:
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1203 set_properties(FixedArray::cast(values)); 1207 set_properties(FixedArray::cast(values));
1204 } 1208 }
1205 set_map(new_map); 1209 set_map(new_map);
1206 return FastPropertyAtPut(index, value); 1210 return FastPropertyAtPut(index, value);
1207 } 1211 }
1208 1212
1209 1213
1210 MaybeObject* JSObject::AddFastProperty(String* name, 1214 MaybeObject* JSObject::AddFastProperty(String* name,
1211 Object* value, 1215 Object* value,
1212 PropertyAttributes attributes) { 1216 PropertyAttributes attributes) {
1217 ASSERT(!IsJSGlobalProxy());
1218
1213 // Normalize the object if the name is an actual string (not the 1219 // Normalize the object if the name is an actual string (not the
1214 // hidden symbols) and is not a real identifier. 1220 // hidden symbols) and is not a real identifier.
1215 StringInputBuffer buffer(name); 1221 StringInputBuffer buffer(name);
1216 if (!ScannerConstants::IsIdentifier(&buffer) 1222 if (!ScannerConstants::IsIdentifier(&buffer)
1217 && name != Heap::hidden_symbol()) { 1223 && name != Heap::hidden_symbol()) {
1218 Object* obj; 1224 Object* obj;
1219 { MaybeObject* maybe_obj = 1225 { MaybeObject* maybe_obj =
1220 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 1226 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1221 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1227 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1222 } 1228 }
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 } 1393 }
1388 1394
1389 1395
1390 MaybeObject* JSObject::AddProperty(String* name, 1396 MaybeObject* JSObject::AddProperty(String* name,
1391 Object* value, 1397 Object* value,
1392 PropertyAttributes attributes) { 1398 PropertyAttributes attributes) {
1393 ASSERT(!IsJSGlobalProxy()); 1399 ASSERT(!IsJSGlobalProxy());
1394 if (!map()->is_extensible()) { 1400 if (!map()->is_extensible()) {
1395 Handle<Object> args[1] = {Handle<String>(name)}; 1401 Handle<Object> args[1] = {Handle<String>(name)};
1396 return Top::Throw(*Factory::NewTypeError("object_not_extensible", 1402 return Top::Throw(*Factory::NewTypeError("object_not_extensible",
1397 HandleVector(args, 1))); 1403 HandleVector(args, 1)));
1398 } 1404 }
1399 if (HasFastProperties()) { 1405 if (HasFastProperties()) {
1400 // Ensure the descriptor array does not get too big. 1406 // Ensure the descriptor array does not get too big.
1401 if (map()->instance_descriptors()->number_of_descriptors() < 1407 if (map()->instance_descriptors()->number_of_descriptors() <
1402 DescriptorArray::kMaxNumberOfDescriptors) { 1408 DescriptorArray::kMaxNumberOfDescriptors) {
1403 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { 1409 if (value->IsJSFunction() && !Heap::InNewSpace(value)) {
1404 return AddConstantFunctionProperty(name, 1410 return AddConstantFunctionProperty(name,
1405 JSFunction::cast(value), 1411 JSFunction::cast(value),
1406 attributes); 1412 attributes);
1407 } else { 1413 } else {
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1695 } 1701 }
1696 if (result->type() == CALLBACKS) { 1702 if (result->type() == CALLBACKS) {
1697 return; 1703 return;
1698 } 1704 }
1699 } 1705 }
1700 } 1706 }
1701 result->NotFound(); 1707 result->NotFound();
1702 } 1708 }
1703 1709
1704 1710
1705 bool JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index, 1711 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index,
1706 Object* value) { 1712 Object* value,
1713 bool* found) {
1707 for (Object* pt = GetPrototype(); 1714 for (Object* pt = GetPrototype();
1708 pt != Heap::null_value(); 1715 pt != Heap::null_value();
1709 pt = pt->GetPrototype()) { 1716 pt = pt->GetPrototype()) {
1710 if (!JSObject::cast(pt)->HasDictionaryElements()) { 1717 if (!JSObject::cast(pt)->HasDictionaryElements()) {
1711 continue; 1718 continue;
1712 } 1719 }
1713 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); 1720 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary();
1714 int entry = dictionary->FindEntry(index); 1721 int entry = dictionary->FindEntry(index);
1715 if (entry != NumberDictionary::kNotFound) { 1722 if (entry != NumberDictionary::kNotFound) {
1716 Object* element = dictionary->ValueAt(entry);
1717 PropertyDetails details = dictionary->DetailsAt(entry); 1723 PropertyDetails details = dictionary->DetailsAt(entry);
1718 if (details.type() == CALLBACKS) { 1724 if (details.type() == CALLBACKS) {
1719 SetElementWithCallback(element, index, value, JSObject::cast(pt)); 1725 *found = true;
1720 return true; 1726 return SetElementWithCallback(
1727 dictionary->ValueAt(entry), index, value, JSObject::cast(pt));
1721 } 1728 }
1722 } 1729 }
1723 } 1730 }
1724 return false; 1731 *found = false;
1732 return Heap::the_hole_value();
1725 } 1733 }
1726 1734
1727 1735
1728 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { 1736 void JSObject::LookupInDescriptor(String* name, LookupResult* result) {
1729 DescriptorArray* descriptors = map()->instance_descriptors(); 1737 DescriptorArray* descriptors = map()->instance_descriptors();
1730 int number = descriptors->SearchWithCache(name); 1738 int number = descriptors->SearchWithCache(name);
1731 if (number != DescriptorArray::kNotFound) { 1739 if (number != DescriptorArray::kNotFound) {
1732 result->DescriptorResult(this, descriptors->GetDetails(number), number); 1740 result->DescriptorResult(this, descriptors->GetDetails(number), number);
1733 } else { 1741 } else {
1734 result->NotFound(); 1742 result->NotFound();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1817 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); 1825 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
1818 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; 1826 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return;
1819 } 1827 }
1820 result->NotFound(); 1828 result->NotFound();
1821 } 1829 }
1822 1830
1823 1831
1824 // We only need to deal with CALLBACKS and INTERCEPTORS 1832 // We only need to deal with CALLBACKS and INTERCEPTORS
1825 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, 1833 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result,
1826 String* name, 1834 String* name,
1827 Object* value) { 1835 Object* value,
1828 if (!result->IsProperty()) { 1836 bool check_prototype) {
1837 if (check_prototype && !result->IsProperty()) {
1829 LookupCallbackSetterInPrototypes(name, result); 1838 LookupCallbackSetterInPrototypes(name, result);
1830 } 1839 }
1831 1840
1832 if (result->IsProperty()) { 1841 if (result->IsProperty()) {
1833 if (!result->IsReadOnly()) { 1842 if (!result->IsReadOnly()) {
1834 switch (result->type()) { 1843 switch (result->type()) {
1835 case CALLBACKS: { 1844 case CALLBACKS: {
1836 Object* obj = result->GetCallbackObject(); 1845 Object* obj = result->GetCallbackObject();
1837 if (obj->IsAccessorInfo()) { 1846 if (obj->IsAccessorInfo()) {
1838 AccessorInfo* info = AccessorInfo::cast(obj); 1847 AccessorInfo* info = AccessorInfo::cast(obj);
1839 if (info->all_can_write()) { 1848 if (info->all_can_write()) {
1840 return SetPropertyWithCallback(result->GetCallbackObject(), 1849 return SetPropertyWithCallback(result->GetCallbackObject(),
1841 name, 1850 name,
1842 value, 1851 value,
1843 result->holder()); 1852 result->holder());
1844 } 1853 }
1845 } 1854 }
1846 break; 1855 break;
1847 } 1856 }
1848 case INTERCEPTOR: { 1857 case INTERCEPTOR: {
1849 // Try lookup real named properties. Note that only property can be 1858 // Try lookup real named properties. Note that only property can be
1850 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. 1859 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain.
1851 LookupResult r; 1860 LookupResult r;
1852 LookupRealNamedProperty(name, &r); 1861 LookupRealNamedProperty(name, &r);
1853 if (r.IsProperty()) { 1862 if (r.IsProperty()) {
1854 return SetPropertyWithFailedAccessCheck(&r, name, value); 1863 return SetPropertyWithFailedAccessCheck(&r, name, value,
1864 check_prototype);
1855 } 1865 }
1856 break; 1866 break;
1857 } 1867 }
1858 default: { 1868 default: {
1859 break; 1869 break;
1860 } 1870 }
1861 } 1871 }
1862 } 1872 }
1863 } 1873 }
1864 1874
(...skipping 20 matching lines...) Expand all
1885 { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name); 1895 { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name);
1886 if (maybe_symbol_version->ToObject(&symbol_version)) { 1896 if (maybe_symbol_version->ToObject(&symbol_version)) {
1887 name = String::cast(symbol_version); 1897 name = String::cast(symbol_version);
1888 } 1898 }
1889 } 1899 }
1890 } 1900 }
1891 1901
1892 // Check access rights if needed. 1902 // Check access rights if needed.
1893 if (IsAccessCheckNeeded() 1903 if (IsAccessCheckNeeded()
1894 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { 1904 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
1895 return SetPropertyWithFailedAccessCheck(result, name, value); 1905 return SetPropertyWithFailedAccessCheck(result, name, value, true);
1896 } 1906 }
1897 1907
1898 if (IsJSGlobalProxy()) { 1908 if (IsJSGlobalProxy()) {
1899 Object* proto = GetPrototype(); 1909 Object* proto = GetPrototype();
1900 if (proto->IsNull()) return value; 1910 if (proto->IsNull()) return value;
1901 ASSERT(proto->IsJSGlobalObject()); 1911 ASSERT(proto->IsJSGlobalObject());
1902 return JSObject::cast(proto)->SetProperty(result, name, value, attributes); 1912 return JSObject::cast(proto)->SetProperty(result, name, value, attributes);
1903 } 1913 }
1904 1914
1905 if (!result->IsProperty() && !IsJSContextExtensionObject()) { 1915 if (!result->IsProperty() && !IsJSContextExtensionObject()) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1975 return value; 1985 return value;
1976 } 1986 }
1977 1987
1978 1988
1979 // Set a real local property, even if it is READ_ONLY. If the property is not 1989 // Set a real local property, even if it is READ_ONLY. If the property is not
1980 // present, add it with attributes NONE. This code is an exact clone of 1990 // present, add it with attributes NONE. This code is an exact clone of
1981 // SetProperty, with the check for IsReadOnly and the check for a 1991 // SetProperty, with the check for IsReadOnly and the check for a
1982 // callback setter removed. The two lines looking up the LookupResult 1992 // callback setter removed. The two lines looking up the LookupResult
1983 // result are also added. If one of the functions is changed, the other 1993 // result are also added. If one of the functions is changed, the other
1984 // should be. 1994 // should be.
1985 MaybeObject* JSObject::IgnoreAttributesAndSetLocalProperty( 1995 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
1986 String* name, 1996 String* name,
1987 Object* value, 1997 Object* value,
1988 PropertyAttributes attributes) { 1998 PropertyAttributes attributes) {
1989 // Make sure that the top context does not change when doing callbacks or 1999 // Make sure that the top context does not change when doing callbacks or
1990 // interceptor calls. 2000 // interceptor calls.
1991 AssertNoContextChange ncc; 2001 AssertNoContextChange ncc;
1992 LookupResult result; 2002 LookupResult result;
1993 LocalLookup(name, &result); 2003 LocalLookup(name, &result);
1994 // Check access rights if needed. 2004 // Check access rights if needed.
1995 if (IsAccessCheckNeeded() 2005 if (IsAccessCheckNeeded()
1996 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { 2006 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
1997 return SetPropertyWithFailedAccessCheck(&result, name, value); 2007 return SetPropertyWithFailedAccessCheck(&result, name, value, false);
1998 } 2008 }
1999 2009
2000 if (IsJSGlobalProxy()) { 2010 if (IsJSGlobalProxy()) {
2001 Object* proto = GetPrototype(); 2011 Object* proto = GetPrototype();
2002 if (proto->IsNull()) return value; 2012 if (proto->IsNull()) return value;
2003 ASSERT(proto->IsJSGlobalObject()); 2013 ASSERT(proto->IsJSGlobalObject());
2004 return JSObject::cast(proto)->IgnoreAttributesAndSetLocalProperty( 2014 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes(
2005 name, 2015 name,
2006 value, 2016 value,
2007 attributes); 2017 attributes);
2008 } 2018 }
2009 2019
2010 // Check for accessor in prototype chain removed here in clone. 2020 // Check for accessor in prototype chain removed here in clone.
2011 if (!result.IsFound()) { 2021 if (!result.IsFound()) {
2012 // Neither properties nor transitions found. 2022 // Neither properties nor transitions found.
2013 return AddProperty(name, value, attributes); 2023 return AddProperty(name, value, attributes);
2014 } 2024 }
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
2276 } 2286 }
2277 2287
2278 2288
2279 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, 2289 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
2280 int expected_additional_properties) { 2290 int expected_additional_properties) {
2281 if (!HasFastProperties()) return this; 2291 if (!HasFastProperties()) return this;
2282 2292
2283 // The global object is always normalized. 2293 // The global object is always normalized.
2284 ASSERT(!IsGlobalObject()); 2294 ASSERT(!IsGlobalObject());
2285 2295
2296 // JSGlobalProxy must never be normalized
2297 ASSERT(!IsJSGlobalProxy());
2298
2286 // Allocate new content. 2299 // Allocate new content.
2287 int property_count = map()->NumberOfDescribedProperties(); 2300 int property_count = map()->NumberOfDescribedProperties();
2288 if (expected_additional_properties > 0) { 2301 if (expected_additional_properties > 0) {
2289 property_count += expected_additional_properties; 2302 property_count += expected_additional_properties;
2290 } else { 2303 } else {
2291 property_count += 2; // Make space for two more properties. 2304 property_count += 2; // Make space for two more properties.
2292 } 2305 }
2293 Object* obj; 2306 Object* obj;
2294 { MaybeObject* maybe_obj = 2307 { MaybeObject* maybe_obj =
2295 StringDictionary::Allocate(property_count); 2308 StringDictionary::Allocate(property_count);
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
2601 case EXTERNAL_INT_ELEMENTS: 2614 case EXTERNAL_INT_ELEMENTS:
2602 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2615 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2603 case EXTERNAL_FLOAT_ELEMENTS: 2616 case EXTERNAL_FLOAT_ELEMENTS:
2604 // Pixel and external array elements cannot be deleted. Just 2617 // Pixel and external array elements cannot be deleted. Just
2605 // silently ignore here. 2618 // silently ignore here.
2606 break; 2619 break;
2607 case DICTIONARY_ELEMENTS: { 2620 case DICTIONARY_ELEMENTS: {
2608 NumberDictionary* dictionary = element_dictionary(); 2621 NumberDictionary* dictionary = element_dictionary();
2609 int entry = dictionary->FindEntry(index); 2622 int entry = dictionary->FindEntry(index);
2610 if (entry != NumberDictionary::kNotFound) { 2623 if (entry != NumberDictionary::kNotFound) {
2611 return dictionary->DeleteProperty(entry, mode); 2624 Object* result = dictionary->DeleteProperty(entry, mode);
2625 if (mode == STRICT_DELETION && result == Heap::false_value()) {
2626 // In strict mode, deleting a non-configurable property throws
2627 // exception. dictionary->DeleteProperty will return false_value()
2628 // if a non-configurable property is being deleted.
2629 HandleScope scope;
2630 Handle<Object> i = Factory::NewNumberFromUint(index);
2631 Handle<Object> args[2] = { i, Handle<Object>(this) };
2632 return Top::Throw(*Factory::NewTypeError("strict_delete_property",
2633 HandleVector(args, 2)));
2634 }
2612 } 2635 }
2613 break; 2636 break;
2614 } 2637 }
2615 default: 2638 default:
2616 UNREACHABLE(); 2639 UNREACHABLE();
2617 break; 2640 break;
2618 } 2641 }
2619 return Heap::true_value(); 2642 return Heap::true_value();
2620 } 2643 }
2621 2644
(...skipping 18 matching lines...) Expand all
2640 2663
2641 uint32_t index = 0; 2664 uint32_t index = 0;
2642 if (name->AsArrayIndex(&index)) { 2665 if (name->AsArrayIndex(&index)) {
2643 return DeleteElement(index, mode); 2666 return DeleteElement(index, mode);
2644 } else { 2667 } else {
2645 LookupResult result; 2668 LookupResult result;
2646 LocalLookup(name, &result); 2669 LocalLookup(name, &result);
2647 if (!result.IsProperty()) return Heap::true_value(); 2670 if (!result.IsProperty()) return Heap::true_value();
2648 // Ignore attributes if forcing a deletion. 2671 // Ignore attributes if forcing a deletion.
2649 if (result.IsDontDelete() && mode != FORCE_DELETION) { 2672 if (result.IsDontDelete() && mode != FORCE_DELETION) {
2673 if (mode == STRICT_DELETION) {
2674 // Deleting a non-configurable property in strict mode.
2675 HandleScope scope;
2676 Handle<Object> args[2] = { Handle<Object>(name), Handle<Object>(this) };
2677 return Top::Throw(*Factory::NewTypeError("strict_delete_property",
2678 HandleVector(args, 2)));
2679 }
2650 return Heap::false_value(); 2680 return Heap::false_value();
2651 } 2681 }
2652 // Check for interceptor. 2682 // Check for interceptor.
2653 if (result.type() == INTERCEPTOR) { 2683 if (result.type() == INTERCEPTOR) {
2654 // Skip interceptor if forcing a deletion. 2684 // Skip interceptor if forcing a deletion.
2655 if (mode == FORCE_DELETION) { 2685 if (mode == FORCE_DELETION) {
2656 return DeletePropertyPostInterceptor(name, mode); 2686 return DeletePropertyPostInterceptor(name, mode);
2657 } 2687 }
2658 return DeletePropertyWithInterceptor(name); 2688 return DeletePropertyWithInterceptor(name);
2659 } 2689 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2762 return context->extension()->ReferencesObject(obj); 2792 return context->extension()->ReferencesObject(obj);
2763 } 2793 }
2764 } 2794 }
2765 2795
2766 // No references to object. 2796 // No references to object.
2767 return false; 2797 return false;
2768 } 2798 }
2769 2799
2770 2800
2771 MaybeObject* JSObject::PreventExtensions() { 2801 MaybeObject* JSObject::PreventExtensions() {
2802 if (IsJSGlobalProxy()) {
2803 Object* proto = GetPrototype();
2804 if (proto->IsNull()) return this;
2805 ASSERT(proto->IsJSGlobalObject());
2806 return JSObject::cast(proto)->PreventExtensions();
2807 }
2808
2772 // If there are fast elements we normalize. 2809 // If there are fast elements we normalize.
2773 if (HasFastElements()) { 2810 if (HasFastElements()) {
2774 Object* ok; 2811 Object* ok;
2775 { MaybeObject* maybe_ok = NormalizeElements(); 2812 { MaybeObject* maybe_ok = NormalizeElements();
2776 if (!maybe_ok->ToObject(&ok)) return maybe_ok; 2813 if (!maybe_ok->ToObject(&ok)) return maybe_ok;
2777 } 2814 }
2778 } 2815 }
2779 // Make sure that we never go back to fast case. 2816 // Make sure that we never go back to fast case.
2780 element_dictionary()->set_requires_slow_elements(); 2817 element_dictionary()->set_requires_slow_elements();
2781 2818
(...skipping 2609 matching lines...) Expand 10 before | Expand all | Expand 10 after
5391 // Iterate over all fields in the body but take care in dealing with 5428 // Iterate over all fields in the body but take care in dealing with
5392 // the code entry. 5429 // the code entry.
5393 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); 5430 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset);
5394 v->VisitCodeEntry(this->address() + kCodeEntryOffset); 5431 v->VisitCodeEntry(this->address() + kCodeEntryOffset);
5395 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); 5432 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size);
5396 } 5433 }
5397 5434
5398 5435
5399 void JSFunction::MarkForLazyRecompilation() { 5436 void JSFunction::MarkForLazyRecompilation() {
5400 ASSERT(is_compiled() && !IsOptimized()); 5437 ASSERT(is_compiled() && !IsOptimized());
5401 ASSERT(shared()->allows_lazy_compilation()); 5438 ASSERT(shared()->allows_lazy_compilation() ||
5439 code()->optimizable());
5402 ReplaceCode(Builtins::builtin(Builtins::LazyRecompile)); 5440 ReplaceCode(Builtins::builtin(Builtins::LazyRecompile));
5403 } 5441 }
5404 5442
5405 5443
5406 uint32_t JSFunction::SourceHash() { 5444 uint32_t JSFunction::SourceHash() {
5407 uint32_t hash = 0; 5445 uint32_t hash = 0;
5408 Object* script = shared()->script(); 5446 Object* script = shared()->script();
5409 if (!script->IsUndefined()) { 5447 if (!script->IsUndefined()) {
5410 Object* source = Script::cast(script)->source(); 5448 Object* source = Script::cast(script)->source();
5411 if (source->IsUndefined()) hash = String::cast(source)->Hash(); 5449 if (source->IsUndefined()) hash = String::cast(source)->Hash();
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
5907 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | 5945 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
5908 RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) | 5946 RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
5909 RelocInfo::kApplyMask; 5947 RelocInfo::kApplyMask;
5910 Assembler* origin = desc.origin; // Needed to find target_object on X64. 5948 Assembler* origin = desc.origin; // Needed to find target_object on X64.
5911 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) { 5949 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
5912 RelocInfo::Mode mode = it.rinfo()->rmode(); 5950 RelocInfo::Mode mode = it.rinfo()->rmode();
5913 if (mode == RelocInfo::EMBEDDED_OBJECT) { 5951 if (mode == RelocInfo::EMBEDDED_OBJECT) {
5914 Handle<Object> p = it.rinfo()->target_object_handle(origin); 5952 Handle<Object> p = it.rinfo()->target_object_handle(origin);
5915 it.rinfo()->set_target_object(*p); 5953 it.rinfo()->set_target_object(*p);
5916 } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { 5954 } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
5917 Handle<JSGlobalPropertyCell> cell = it.rinfo()->target_cell_handle(); 5955 Handle<JSGlobalPropertyCell> cell = it.rinfo()->target_cell_handle();
5918 it.rinfo()->set_target_cell(*cell); 5956 it.rinfo()->set_target_cell(*cell);
5919 } else if (RelocInfo::IsCodeTarget(mode)) { 5957 } else if (RelocInfo::IsCodeTarget(mode)) {
5920 // rewrite code handles in inline cache targets to direct 5958 // rewrite code handles in inline cache targets to direct
5921 // pointers to the first instruction in the code object 5959 // pointers to the first instruction in the code object
5922 Handle<Object> p = it.rinfo()->target_object_handle(origin); 5960 Handle<Object> p = it.rinfo()->target_object_handle(origin);
5923 Code* code = Code::cast(*p); 5961 Code* code = Code::cast(*p);
5924 it.rinfo()->set_target_address(code->instruction_start()); 5962 it.rinfo()->set_target_address(code->instruction_start());
5925 } else { 5963 } else {
5926 it.rinfo()->apply(delta); 5964 it.rinfo()->apply(delta);
5927 } 5965 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
5979 if (statement_position < p && p <= position) { 6017 if (statement_position < p && p <= position) {
5980 statement_position = p; 6018 statement_position = p;
5981 } 6019 }
5982 } 6020 }
5983 it.next(); 6021 it.next();
5984 } 6022 }
5985 return statement_position; 6023 return statement_position;
5986 } 6024 }
5987 6025
5988 6026
5989 uint8_t* Code::GetSafepointEntry(Address pc) { 6027 SafepointEntry Code::GetSafepointEntry(Address pc) {
5990 SafepointTable table(this); 6028 SafepointTable table(this);
5991 unsigned pc_offset = static_cast<unsigned>(pc - instruction_start()); 6029 return table.FindEntry(pc);
5992 for (unsigned i = 0; i < table.length(); i++) {
5993 // TODO(kasperl): Replace the linear search with binary search.
5994 if (table.GetPcOffset(i) == pc_offset) return table.GetEntry(i);
5995 }
5996 return NULL;
5997 } 6030 }
5998 6031
5999 6032
6000 void Code::SetNoStackCheckTable() { 6033 void Code::SetNoStackCheckTable() {
6001 // Indicate the absence of a stack-check table by a table start after the 6034 // Indicate the absence of a stack-check table by a table start after the
6002 // end of the instructions. Table start must be aligned, so round up. 6035 // end of the instructions. Table start must be aligned, so round up.
6003 set_stack_check_table_start(RoundUp(instruction_size(), kIntSize)); 6036 set_stack_check_table_offset(RoundUp(instruction_size(), kIntSize));
6004 } 6037 }
6005 6038
6006 6039
6007 Map* Code::FindFirstMap() { 6040 Map* Code::FindFirstMap() {
6008 ASSERT(is_inline_cache_stub()); 6041 ASSERT(is_inline_cache_stub());
6009 AssertNoAllocation no_allocation; 6042 AssertNoAllocation no_allocation;
6010 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 6043 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
6011 for (RelocIterator it(this, mask); !it.done(); it.next()) { 6044 for (RelocIterator it(this, mask); !it.done(); it.next()) {
6012 RelocInfo* info = it.rinfo(); 6045 RelocInfo* info = it.rinfo();
6013 Object* object = info->target_object(); 6046 Object* object = info->target_object();
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
6216 case INTERCEPTOR: return "INTERCEPTOR"; 6249 case INTERCEPTOR: return "INTERCEPTOR";
6217 case MAP_TRANSITION: return "MAP_TRANSITION"; 6250 case MAP_TRANSITION: return "MAP_TRANSITION";
6218 case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION"; 6251 case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION";
6219 case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR"; 6252 case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR";
6220 } 6253 }
6221 UNREACHABLE(); 6254 UNREACHABLE();
6222 return NULL; 6255 return NULL;
6223 } 6256 }
6224 6257
6225 6258
6259 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) {
6260 const char* name = NULL;
6261 switch (kind) {
6262 case CALL_IC:
6263 if (extra == STRING_INDEX_OUT_OF_BOUNDS) {
6264 name = "STRING_INDEX_OUT_OF_BOUNDS";
6265 }
6266 break;
6267 case STORE_IC:
6268 if (extra == StoreIC::kStoreICStrict) {
6269 name = "STRICT";
6270 }
6271 break;
6272 default:
6273 break;
6274 }
6275 if (name != NULL) {
6276 PrintF(out, "extra_ic_state = %s\n", name);
6277 } else {
6278 PrintF(out, "etra_ic_state = %d\n", extra);
6279 }
6280 }
6281
6282
6226 void Code::Disassemble(const char* name, FILE* out) { 6283 void Code::Disassemble(const char* name, FILE* out) {
6227 PrintF(out, "kind = %s\n", Kind2String(kind())); 6284 PrintF(out, "kind = %s\n", Kind2String(kind()));
6228 if (is_inline_cache_stub()) { 6285 if (is_inline_cache_stub()) {
6229 PrintF(out, "ic_state = %s\n", ICState2String(ic_state())); 6286 PrintF(out, "ic_state = %s\n", ICState2String(ic_state()));
6287 PrintExtraICState(out, kind(), extra_ic_state());
6230 PrintF(out, "ic_in_loop = %d\n", ic_in_loop() == IN_LOOP); 6288 PrintF(out, "ic_in_loop = %d\n", ic_in_loop() == IN_LOOP);
6231 if (ic_state() == MONOMORPHIC) { 6289 if (ic_state() == MONOMORPHIC) {
6232 PrintF(out, "type = %s\n", PropertyType2String(type())); 6290 PrintF(out, "type = %s\n", PropertyType2String(type()));
6233 } 6291 }
6234 } 6292 }
6235 if ((name != NULL) && (name[0] != '\0')) { 6293 if ((name != NULL) && (name[0] != '\0')) {
6236 PrintF(out, "name = %s\n", name); 6294 PrintF(out, "name = %s\n", name);
6237 } 6295 }
6238 if (kind() == OPTIMIZED_FUNCTION) { 6296 if (kind() == OPTIMIZED_FUNCTION) {
6239 PrintF(out, "stack_slots = %d\n", stack_slots()); 6297 PrintF(out, "stack_slots = %d\n", stack_slots());
(...skipping 17 matching lines...) Expand all
6257 #endif 6315 #endif
6258 6316
6259 if (kind() == OPTIMIZED_FUNCTION) { 6317 if (kind() == OPTIMIZED_FUNCTION) {
6260 SafepointTable table(this); 6318 SafepointTable table(this);
6261 PrintF(out, "Safepoints (size = %u)\n", table.size()); 6319 PrintF(out, "Safepoints (size = %u)\n", table.size());
6262 for (unsigned i = 0; i < table.length(); i++) { 6320 for (unsigned i = 0; i < table.length(); i++) {
6263 unsigned pc_offset = table.GetPcOffset(i); 6321 unsigned pc_offset = table.GetPcOffset(i);
6264 PrintF(out, "%p %4d ", (instruction_start() + pc_offset), pc_offset); 6322 PrintF(out, "%p %4d ", (instruction_start() + pc_offset), pc_offset);
6265 table.PrintEntry(i); 6323 table.PrintEntry(i);
6266 PrintF(out, " (sp -> fp)"); 6324 PrintF(out, " (sp -> fp)");
6267 int deoptimization_index = table.GetDeoptimizationIndex(i); 6325 SafepointEntry entry = table.GetEntry(i);
6268 if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) { 6326 if (entry.deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
6269 PrintF(out, " %6d", deoptimization_index); 6327 PrintF(out, " %6d", entry.deoptimization_index());
6270 } else { 6328 } else {
6271 PrintF(out, " <none>"); 6329 PrintF(out, " <none>");
6272 } 6330 }
6331 if (entry.argument_count() > 0) {
6332 PrintF(out, " argc: %d", entry.argument_count());
6333 }
6273 PrintF(out, "\n"); 6334 PrintF(out, "\n");
6274 } 6335 }
6275 PrintF(out, "\n"); 6336 PrintF(out, "\n");
6276 } else if (kind() == FUNCTION) { 6337 } else if (kind() == FUNCTION) {
6277 unsigned offset = stack_check_table_start(); 6338 unsigned offset = stack_check_table_offset();
6278 // If there is no stack check table, the "table start" will at or after 6339 // If there is no stack check table, the "table start" will at or after
6279 // (due to alignment) the end of the instruction stream. 6340 // (due to alignment) the end of the instruction stream.
6280 if (static_cast<int>(offset) < instruction_size()) { 6341 if (static_cast<int>(offset) < instruction_size()) {
6281 unsigned* address = 6342 unsigned* address =
6282 reinterpret_cast<unsigned*>(instruction_start() + offset); 6343 reinterpret_cast<unsigned*>(instruction_start() + offset);
6283 unsigned length = address[0]; 6344 unsigned length = address[0];
6284 PrintF(out, "Stack checks (size = %u)\n", length); 6345 PrintF(out, "Stack checks (size = %u)\n", length);
6285 PrintF(out, "ast_id pc_offset\n"); 6346 PrintF(out, "ast_id pc_offset\n");
6286 for (unsigned i = 0; i < length; ++i) { 6347 for (unsigned i = 0; i < length; ++i) {
6287 unsigned index = (2 * i) + 1; 6348 unsigned index = (2 * i) + 1;
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
6668 6729
6669 6730
6670 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) { 6731 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) {
6671 // Check access rights if needed. 6732 // Check access rights if needed.
6672 if (IsAccessCheckNeeded() && 6733 if (IsAccessCheckNeeded() &&
6673 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 6734 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
6674 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 6735 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS);
6675 return UNDEFINED_ELEMENT; 6736 return UNDEFINED_ELEMENT;
6676 } 6737 }
6677 6738
6739 if (IsJSGlobalProxy()) {
6740 Object* proto = GetPrototype();
6741 if (proto->IsNull()) return UNDEFINED_ELEMENT;
6742 ASSERT(proto->IsJSGlobalObject());
6743 return JSObject::cast(proto)->HasLocalElement(index);
6744 }
6745
6678 // Check for lookup interceptor 6746 // Check for lookup interceptor
6679 if (HasIndexedInterceptor()) { 6747 if (HasIndexedInterceptor()) {
6680 return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT 6748 return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT
6681 : UNDEFINED_ELEMENT; 6749 : UNDEFINED_ELEMENT;
6682 } 6750 }
6683 6751
6684 // Handle [] on String objects. 6752 // Handle [] on String objects.
6685 if (this->IsStringObjectWithCharacterAt(index)) { 6753 if (this->IsStringObjectWithCharacterAt(index)) {
6686 return STRING_CHARACTER_ELEMENT; 6754 return STRING_CHARACTER_ELEMENT;
6687 } 6755 }
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
6939 ASSERT(HasFastElements()); 7007 ASSERT(HasFastElements());
6940 7008
6941 Object* elms_obj; 7009 Object* elms_obj;
6942 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); 7010 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements();
6943 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; 7011 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
6944 } 7012 }
6945 FixedArray* elms = FixedArray::cast(elms_obj); 7013 FixedArray* elms = FixedArray::cast(elms_obj);
6946 uint32_t elms_length = static_cast<uint32_t>(elms->length()); 7014 uint32_t elms_length = static_cast<uint32_t>(elms->length());
6947 7015
6948 if (check_prototype && 7016 if (check_prototype &&
6949 (index >= elms_length || elms->get(index)->IsTheHole()) && 7017 (index >= elms_length || elms->get(index)->IsTheHole())) {
6950 SetElementWithCallbackSetterInPrototypes(index, value)) { 7018 bool found;
6951 return value; 7019 MaybeObject* result =
7020 SetElementWithCallbackSetterInPrototypes(index, value, &found);
7021 if (found) return result;
6952 } 7022 }
6953 7023
6954 7024
6955 // Check whether there is extra space in fixed array.. 7025 // Check whether there is extra space in fixed array..
6956 if (index < elms_length) { 7026 if (index < elms_length) {
6957 elms->set(index, value); 7027 elms->set(index, value);
6958 if (IsJSArray()) { 7028 if (IsJSArray()) {
6959 // Update the length of the array if needed. 7029 // Update the length of the array if needed.
6960 uint32_t array_length = 0; 7030 uint32_t array_length = 0;
6961 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); 7031 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length));
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
7073 Object* element = dictionary->ValueAt(entry); 7143 Object* element = dictionary->ValueAt(entry);
7074 PropertyDetails details = dictionary->DetailsAt(entry); 7144 PropertyDetails details = dictionary->DetailsAt(entry);
7075 if (details.type() == CALLBACKS) { 7145 if (details.type() == CALLBACKS) {
7076 return SetElementWithCallback(element, index, value, this); 7146 return SetElementWithCallback(element, index, value, this);
7077 } else { 7147 } else {
7078 dictionary->UpdateMaxNumberKey(index); 7148 dictionary->UpdateMaxNumberKey(index);
7079 dictionary->ValueAtPut(entry, value); 7149 dictionary->ValueAtPut(entry, value);
7080 } 7150 }
7081 } else { 7151 } else {
7082 // Index not already used. Look for an accessor in the prototype chain. 7152 // Index not already used. Look for an accessor in the prototype chain.
7083 if (check_prototype && 7153 if (check_prototype) {
7084 SetElementWithCallbackSetterInPrototypes(index, value)) { 7154 bool found;
7085 return value; 7155 MaybeObject* result =
7156 SetElementWithCallbackSetterInPrototypes(index, value, &found);
7157 if (found) return result;
7086 } 7158 }
7087 // When we set the is_extensible flag to false we always force 7159 // When we set the is_extensible flag to false we always force
7088 // the element into dictionary mode (and force them to stay there). 7160 // the element into dictionary mode (and force them to stay there).
7089 if (!map()->is_extensible()) { 7161 if (!map()->is_extensible()) {
7090 Handle<Object> number(Factory::NewNumberFromUint(index)); 7162 Handle<Object> number(Factory::NewNumberFromUint(index));
7091 Handle<String> index_string(Factory::NumberToString(number)); 7163 Handle<String> index_string(Factory::NumberToString(number));
7092 Handle<Object> args[1] = { index_string }; 7164 Handle<Object> args[1] = { index_string };
7093 return Top::Throw(*Factory::NewTypeError("object_not_extensible", 7165 return Top::Throw(*Factory::NewTypeError("object_not_extensible",
7094 HandleVector(args, 1))); 7166 HandleVector(args, 1)));
7095 } 7167 }
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after
7975 Object* AsObject() { return string_; } 8047 Object* AsObject() { return string_; }
7976 8048
7977 String* string_; 8049 String* string_;
7978 uint32_t hash_; 8050 uint32_t hash_;
7979 }; 8051 };
7980 8052
7981 8053
7982 // StringSharedKeys are used as keys in the eval cache. 8054 // StringSharedKeys are used as keys in the eval cache.
7983 class StringSharedKey : public HashTableKey { 8055 class StringSharedKey : public HashTableKey {
7984 public: 8056 public:
7985 StringSharedKey(String* source, SharedFunctionInfo* shared) 8057 StringSharedKey(String* source,
7986 : source_(source), shared_(shared) { } 8058 SharedFunctionInfo* shared,
8059 StrictModeFlag strict_mode)
8060 : source_(source),
8061 shared_(shared),
8062 strict_mode_(strict_mode) { }
7987 8063
7988 bool IsMatch(Object* other) { 8064 bool IsMatch(Object* other) {
7989 if (!other->IsFixedArray()) return false; 8065 if (!other->IsFixedArray()) return false;
7990 FixedArray* pair = FixedArray::cast(other); 8066 FixedArray* pair = FixedArray::cast(other);
7991 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); 8067 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0));
7992 if (shared != shared_) return false; 8068 if (shared != shared_) return false;
8069 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(
8070 Smi::cast(pair->get(2))->value());
8071 if (strict_mode != strict_mode_) return false;
7993 String* source = String::cast(pair->get(1)); 8072 String* source = String::cast(pair->get(1));
7994 return source->Equals(source_); 8073 return source->Equals(source_);
7995 } 8074 }
7996 8075
7997 static uint32_t StringSharedHashHelper(String* source, 8076 static uint32_t StringSharedHashHelper(String* source,
7998 SharedFunctionInfo* shared) { 8077 SharedFunctionInfo* shared,
8078 StrictModeFlag strict_mode) {
7999 uint32_t hash = source->Hash(); 8079 uint32_t hash = source->Hash();
8000 if (shared->HasSourceCode()) { 8080 if (shared->HasSourceCode()) {
8001 // Instead of using the SharedFunctionInfo pointer in the hash 8081 // Instead of using the SharedFunctionInfo pointer in the hash
8002 // code computation, we use a combination of the hash of the 8082 // code computation, we use a combination of the hash of the
8003 // script source code and the start and end positions. We do 8083 // script source code and the start and end positions. We do
8004 // this to ensure that the cache entries can survive garbage 8084 // this to ensure that the cache entries can survive garbage
8005 // collection. 8085 // collection.
8006 Script* script = Script::cast(shared->script()); 8086 Script* script = Script::cast(shared->script());
8007 hash ^= String::cast(script->source())->Hash(); 8087 hash ^= String::cast(script->source())->Hash();
8088 if (strict_mode == kStrictMode) hash ^= 0x8000;
8008 hash += shared->start_position(); 8089 hash += shared->start_position();
8009 } 8090 }
8010 return hash; 8091 return hash;
8011 } 8092 }
8012 8093
8013 uint32_t Hash() { 8094 uint32_t Hash() {
8014 return StringSharedHashHelper(source_, shared_); 8095 return StringSharedHashHelper(source_, shared_, strict_mode_);
8015 } 8096 }
8016 8097
8017 uint32_t HashForObject(Object* obj) { 8098 uint32_t HashForObject(Object* obj) {
8018 FixedArray* pair = FixedArray::cast(obj); 8099 FixedArray* pair = FixedArray::cast(obj);
8019 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); 8100 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0));
8020 String* source = String::cast(pair->get(1)); 8101 String* source = String::cast(pair->get(1));
8021 return StringSharedHashHelper(source, shared); 8102 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(
8103 Smi::cast(pair->get(2))->value());
8104 return StringSharedHashHelper(source, shared, strict_mode);
8022 } 8105 }
8023 8106
8024 MUST_USE_RESULT MaybeObject* AsObject() { 8107 MUST_USE_RESULT MaybeObject* AsObject() {
8025 Object* obj; 8108 Object* obj;
8026 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(2); 8109 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(3);
8027 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8110 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8028 } 8111 }
8029 FixedArray* pair = FixedArray::cast(obj); 8112 FixedArray* pair = FixedArray::cast(obj);
8030 pair->set(0, shared_); 8113 pair->set(0, shared_);
8031 pair->set(1, source_); 8114 pair->set(1, source_);
8115 pair->set(2, Smi::FromInt(strict_mode_));
8032 return pair; 8116 return pair;
8033 } 8117 }
8034 8118
8035 private: 8119 private:
8036 String* source_; 8120 String* source_;
8037 SharedFunctionInfo* shared_; 8121 SharedFunctionInfo* shared_;
8122 StrictModeFlag strict_mode_;
8038 }; 8123 };
8039 8124
8040 8125
8041 // RegExpKey carries the source and flags of a regular expression as key. 8126 // RegExpKey carries the source and flags of a regular expression as key.
8042 class RegExpKey : public HashTableKey { 8127 class RegExpKey : public HashTableKey {
8043 public: 8128 public:
8044 RegExpKey(String* string, JSRegExp::Flags flags) 8129 RegExpKey(String* string, JSRegExp::Flags flags)
8045 : string_(string), 8130 : string_(string),
8046 flags_(Smi::FromInt(flags.value())) { } 8131 flags_(Smi::FromInt(flags.value())) { }
8047 8132
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
8516 return Smi::FromInt(-1); 8601 return Smi::FromInt(-1);
8517 } 8602 }
8518 uint32_t key = NumberToUint32(k); 8603 uint32_t key = NumberToUint32(k);
8519 // In the following we assert that adding the entry to the new dictionary 8604 // In the following we assert that adding the entry to the new dictionary
8520 // does not cause GC. This is the case because we made sure to allocate 8605 // does not cause GC. This is the case because we made sure to allocate
8521 // the dictionary big enough above, so it need not grow. 8606 // the dictionary big enough above, so it need not grow.
8522 if (key < limit) { 8607 if (key < limit) {
8523 if (value->IsUndefined()) { 8608 if (value->IsUndefined()) {
8524 undefs++; 8609 undefs++;
8525 } else { 8610 } else {
8611 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
8612 // Adding an entry with the key beyond smi-range requires
8613 // allocation. Bailout.
8614 return Smi::FromInt(-1);
8615 }
8526 new_dict->AddNumberEntry(pos, value, details)->ToObjectUnchecked(); 8616 new_dict->AddNumberEntry(pos, value, details)->ToObjectUnchecked();
8527 pos++; 8617 pos++;
8528 } 8618 }
8529 } else { 8619 } else {
8620 if (key > static_cast<uint32_t>(Smi::kMaxValue)) {
8621 // Adding an entry with the key beyond smi-range requires
8622 // allocation. Bailout.
8623 return Smi::FromInt(-1);
8624 }
8530 new_dict->AddNumberEntry(key, value, details)->ToObjectUnchecked(); 8625 new_dict->AddNumberEntry(key, value, details)->ToObjectUnchecked();
8531 } 8626 }
8532 } 8627 }
8533 } 8628 }
8534 8629
8535 uint32_t result = pos; 8630 uint32_t result = pos;
8536 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); 8631 PropertyDetails no_details = PropertyDetails(NONE, NORMAL);
8537 while (undefs > 0) { 8632 while (undefs > 0) {
8633 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
8634 // Adding an entry with the key beyond smi-range requires
8635 // allocation. Bailout.
8636 return Smi::FromInt(-1);
8637 }
8538 new_dict->AddNumberEntry(pos, Heap::undefined_value(), no_details)-> 8638 new_dict->AddNumberEntry(pos, Heap::undefined_value(), no_details)->
8539 ToObjectUnchecked(); 8639 ToObjectUnchecked();
8540 pos++; 8640 pos++;
8541 undefs--; 8641 undefs--;
8542 } 8642 }
8543 8643
8544 set_elements(new_dict); 8644 set_elements(new_dict);
8545 8645
8546 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { 8646 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) {
8547 return Smi::FromInt(static_cast<int>(result)); 8647 return Smi::FromInt(static_cast<int>(result));
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
8986 9086
8987 9087
8988 Object* CompilationCacheTable::Lookup(String* src) { 9088 Object* CompilationCacheTable::Lookup(String* src) {
8989 StringKey key(src); 9089 StringKey key(src);
8990 int entry = FindEntry(&key); 9090 int entry = FindEntry(&key);
8991 if (entry == kNotFound) return Heap::undefined_value(); 9091 if (entry == kNotFound) return Heap::undefined_value();
8992 return get(EntryToIndex(entry) + 1); 9092 return get(EntryToIndex(entry) + 1);
8993 } 9093 }
8994 9094
8995 9095
8996 Object* CompilationCacheTable::LookupEval(String* src, Context* context) { 9096 Object* CompilationCacheTable::LookupEval(String* src,
8997 StringSharedKey key(src, context->closure()->shared()); 9097 Context* context,
9098 StrictModeFlag strict_mode) {
9099 StringSharedKey key(src, context->closure()->shared(), strict_mode);
8998 int entry = FindEntry(&key); 9100 int entry = FindEntry(&key);
8999 if (entry == kNotFound) return Heap::undefined_value(); 9101 if (entry == kNotFound) return Heap::undefined_value();
9000 return get(EntryToIndex(entry) + 1); 9102 return get(EntryToIndex(entry) + 1);
9001 } 9103 }
9002 9104
9003 9105
9004 Object* CompilationCacheTable::LookupRegExp(String* src, 9106 Object* CompilationCacheTable::LookupRegExp(String* src,
9005 JSRegExp::Flags flags) { 9107 JSRegExp::Flags flags) {
9006 RegExpKey key(src, flags); 9108 RegExpKey key(src, flags);
9007 int entry = FindEntry(&key); 9109 int entry = FindEntry(&key);
(...skipping 14 matching lines...) Expand all
9022 int entry = cache->FindInsertionEntry(key.Hash()); 9124 int entry = cache->FindInsertionEntry(key.Hash());
9023 cache->set(EntryToIndex(entry), src); 9125 cache->set(EntryToIndex(entry), src);
9024 cache->set(EntryToIndex(entry) + 1, value); 9126 cache->set(EntryToIndex(entry) + 1, value);
9025 cache->ElementAdded(); 9127 cache->ElementAdded();
9026 return cache; 9128 return cache;
9027 } 9129 }
9028 9130
9029 9131
9030 MaybeObject* CompilationCacheTable::PutEval(String* src, 9132 MaybeObject* CompilationCacheTable::PutEval(String* src,
9031 Context* context, 9133 Context* context,
9032 Object* value) { 9134 SharedFunctionInfo* value) {
9033 StringSharedKey key(src, context->closure()->shared()); 9135 StringSharedKey key(src,
9136 context->closure()->shared(),
9137 value->strict_mode() ? kStrictMode : kNonStrictMode);
9034 Object* obj; 9138 Object* obj;
9035 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); 9139 { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
9036 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9140 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
9037 } 9141 }
9038 9142
9039 CompilationCacheTable* cache = 9143 CompilationCacheTable* cache =
9040 reinterpret_cast<CompilationCacheTable*>(obj); 9144 reinterpret_cast<CompilationCacheTable*>(obj);
9041 int entry = cache->FindInsertionEntry(key.Hash()); 9145 int entry = cache->FindInsertionEntry(key.Hash());
9042 9146
9043 Object* k; 9147 Object* k;
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
9252 // Update the number of elements. 9356 // Update the number of elements.
9253 ElementsRemoved(removed_entries); 9357 ElementsRemoved(removed_entries);
9254 } 9358 }
9255 9359
9256 9360
9257 template<typename Shape, typename Key> 9361 template<typename Shape, typename Key>
9258 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, 9362 Object* Dictionary<Shape, Key>::DeleteProperty(int entry,
9259 JSObject::DeleteMode mode) { 9363 JSObject::DeleteMode mode) {
9260 PropertyDetails details = DetailsAt(entry); 9364 PropertyDetails details = DetailsAt(entry);
9261 // Ignore attributes if forcing a deletion. 9365 // Ignore attributes if forcing a deletion.
9262 if (details.IsDontDelete() && mode == JSObject::NORMAL_DELETION) { 9366 if (details.IsDontDelete() && mode != JSObject::FORCE_DELETION) {
9263 return Heap::false_value(); 9367 return Heap::false_value();
9264 } 9368 }
9265 SetEntry(entry, Heap::null_value(), Heap::null_value(), Smi::FromInt(0)); 9369 SetEntry(entry, Heap::null_value(), Heap::null_value(), Smi::FromInt(0));
9266 HashTable<Shape, Key>::ElementRemoved(); 9370 HashTable<Shape, Key>::ElementRemoved();
9267 return Heap::true_value(); 9371 return Heap::true_value();
9268 } 9372 }
9269 9373
9270 9374
9271 template<typename Shape, typename Key> 9375 template<typename Shape, typename Key>
9272 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { 9376 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) {
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
9867 if (break_point_objects()->IsUndefined()) return 0; 9971 if (break_point_objects()->IsUndefined()) return 0;
9868 // Single beak point. 9972 // Single beak point.
9869 if (!break_point_objects()->IsFixedArray()) return 1; 9973 if (!break_point_objects()->IsFixedArray()) return 1;
9870 // Multiple break points. 9974 // Multiple break points.
9871 return FixedArray::cast(break_point_objects())->length(); 9975 return FixedArray::cast(break_point_objects())->length();
9872 } 9976 }
9873 #endif 9977 #endif
9874 9978
9875 9979
9876 } } // namespace v8::internal 9980 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698