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

Side by Side Diff: src/objects.cc

Issue 151163005: A64: Synchronize with r16356. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 // TODO(rossberg): Handling symbols in the API requires changing the API, 361 // TODO(rossberg): Handling symbols in the API requires changing the API,
362 // so we do not support it for now. 362 // so we do not support it for now.
363 if (name->IsSymbol()) return isolate->heap()->undefined_value(); 363 if (name->IsSymbol()) return isolate->heap()->undefined_value();
364 if (structure->IsDeclaredAccessorInfo()) { 364 if (structure->IsDeclaredAccessorInfo()) {
365 return GetDeclaredAccessorProperty(receiver, 365 return GetDeclaredAccessorProperty(receiver,
366 DeclaredAccessorInfo::cast(structure), 366 DeclaredAccessorInfo::cast(structure),
367 isolate); 367 isolate);
368 } 368 }
369 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure); 369 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure);
370 Object* fun_obj = data->getter(); 370 Object* fun_obj = data->getter();
371 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); 371 v8::AccessorGetterCallback call_fun =
372 v8::ToCData<v8::AccessorGetterCallback>(fun_obj);
372 if (call_fun == NULL) return isolate->heap()->undefined_value(); 373 if (call_fun == NULL) return isolate->heap()->undefined_value();
373 HandleScope scope(isolate); 374 HandleScope scope(isolate);
374 JSObject* self = JSObject::cast(receiver); 375 JSObject* self = JSObject::cast(receiver);
375 Handle<String> key(String::cast(name)); 376 Handle<String> key(String::cast(name));
376 LOG(isolate, ApiNamedPropertyAccess("load", self, name)); 377 LOG(isolate, ApiNamedPropertyAccess("load", self, name));
377 PropertyCallbackArguments args(isolate, data->data(), self, this); 378 PropertyCallbackArguments args(isolate, data->data(), self, this);
378 v8::Handle<v8::Value> result = 379 v8::Handle<v8::Value> result =
379 args.Call(call_fun, v8::Utils::ToLocal(key)); 380 args.Call(call_fun, v8::Utils::ToLocal(key));
380 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 381 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
381 if (result.IsEmpty()) { 382 if (result.IsEmpty()) {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 case CALLBACKS: { 507 case CALLBACKS: {
507 // Only allow API accessors. 508 // Only allow API accessors.
508 Object* obj = result->GetCallbackObject(); 509 Object* obj = result->GetCallbackObject();
509 if (obj->IsAccessorInfo()) { 510 if (obj->IsAccessorInfo()) {
510 AccessorInfo* info = AccessorInfo::cast(obj); 511 AccessorInfo* info = AccessorInfo::cast(obj);
511 if (info->all_can_read()) { 512 if (info->all_can_read()) {
512 *attributes = result->GetAttributes(); 513 *attributes = result->GetAttributes();
513 return result->holder()->GetPropertyWithCallback( 514 return result->holder()->GetPropertyWithCallback(
514 receiver, result->GetCallbackObject(), name); 515 receiver, result->GetCallbackObject(), name);
515 } 516 }
517 } else if (obj->IsAccessorPair()) {
518 AccessorPair* pair = AccessorPair::cast(obj);
519 if (pair->all_can_read()) {
520 return result->holder()->GetPropertyWithCallback(
521 receiver, result->GetCallbackObject(), name);
522 }
516 } 523 }
517 break; 524 break;
518 } 525 }
519 case NORMAL: 526 case NORMAL:
520 case FIELD: 527 case FIELD:
521 case CONSTANT: { 528 case CONSTANT: {
522 // Search ALL_CAN_READ accessors in prototype chain. 529 // Search ALL_CAN_READ accessors in prototype chain.
523 LookupResult r(GetIsolate()); 530 LookupResult r(GetIsolate());
524 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); 531 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
525 if (r.IsProperty()) { 532 if (r.IsProperty()) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 if (result->IsProperty()) { 573 if (result->IsProperty()) {
567 switch (result->type()) { 574 switch (result->type()) {
568 case CALLBACKS: { 575 case CALLBACKS: {
569 // Only allow API accessors. 576 // Only allow API accessors.
570 Object* obj = result->GetCallbackObject(); 577 Object* obj = result->GetCallbackObject();
571 if (obj->IsAccessorInfo()) { 578 if (obj->IsAccessorInfo()) {
572 AccessorInfo* info = AccessorInfo::cast(obj); 579 AccessorInfo* info = AccessorInfo::cast(obj);
573 if (info->all_can_read()) { 580 if (info->all_can_read()) {
574 return result->GetAttributes(); 581 return result->GetAttributes();
575 } 582 }
583 } else if (obj->IsAccessorPair()) {
584 AccessorPair* pair = AccessorPair::cast(obj);
585 if (pair->all_can_read()) {
586 return result->GetAttributes();
587 }
576 } 588 }
577 break; 589 break;
578 } 590 }
579 591
580 case NORMAL: 592 case NORMAL:
581 case FIELD: 593 case FIELD:
582 case CONSTANT: { 594 case CONSTANT: {
583 if (!continue_search) break; 595 if (!continue_search) break;
584 // Search ALL_CAN_READ accessors in prototype chain. 596 // Search ALL_CAN_READ accessors in prototype chain.
585 LookupResult r(GetIsolate()); 597 LookupResult r(GetIsolate());
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 PrintF(file, " from "); 1455 PrintF(file, " from ");
1444 from_elements->ShortPrint(file); 1456 from_elements->ShortPrint(file);
1445 PrintF(file, " to "); 1457 PrintF(file, " to ");
1446 to_elements->ShortPrint(file); 1458 to_elements->ShortPrint(file);
1447 PrintF(file, "\n"); 1459 PrintF(file, "\n");
1448 } 1460 }
1449 } 1461 }
1450 1462
1451 1463
1452 void Map::PrintGeneralization(FILE* file, 1464 void Map::PrintGeneralization(FILE* file,
1465 const char* reason,
1453 int modify_index, 1466 int modify_index,
1454 int split, 1467 int split,
1455 int descriptors, 1468 int descriptors,
1469 bool constant_to_field,
1456 Representation old_representation, 1470 Representation old_representation,
1457 Representation new_representation) { 1471 Representation new_representation) {
1458 PrintF(file, "[generalizing "); 1472 PrintF(file, "[generalizing ");
1459 constructor_name()->PrintOn(file); 1473 constructor_name()->PrintOn(file);
1460 PrintF(file, "] "); 1474 PrintF(file, "] ");
1461 String::cast(instance_descriptors()->GetKey(modify_index))->PrintOn(file); 1475 String::cast(instance_descriptors()->GetKey(modify_index))->PrintOn(file);
1462 PrintF(file, ":%s->%s (+%i maps) [", 1476 if (constant_to_field) {
1463 old_representation.Mnemonic(), 1477 PrintF(file, ":c->f");
1464 new_representation.Mnemonic(), 1478 } else {
1465 descriptors - split); 1479 PrintF(file, ":%s->%s",
1480 old_representation.Mnemonic(),
1481 new_representation.Mnemonic());
1482 }
1483 PrintF(file, " (");
1484 if (strlen(reason) > 0) {
1485 PrintF(file, "%s", reason);
1486 } else {
1487 PrintF(file, "+%i maps", descriptors - split);
1488 }
1489 PrintF(file, ") [");
1466 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); 1490 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
1467 PrintF(file, "]\n"); 1491 PrintF(file, "]\n");
1468 } 1492 }
1469 1493
1470 1494
1471 void JSObject::PrintInstanceMigration(FILE* file, 1495 void JSObject::PrintInstanceMigration(FILE* file,
1472 Map* original_map, 1496 Map* original_map,
1473 Map* new_map) { 1497 Map* new_map) {
1474 PrintF(file, "[migrating "); 1498 PrintF(file, "[migrating ");
1475 map()->constructor_name()->PrintOn(file); 1499 map()->constructor_name()->PrintOn(file);
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
1897 } 1921 }
1898 } 1922 }
1899 return true; 1923 return true;
1900 } 1924 }
1901 1925
1902 1926
1903 MaybeObject* JSObject::AddFastProperty(Name* name, 1927 MaybeObject* JSObject::AddFastProperty(Name* name,
1904 Object* value, 1928 Object* value,
1905 PropertyAttributes attributes, 1929 PropertyAttributes attributes,
1906 StoreFromKeyed store_mode, 1930 StoreFromKeyed store_mode,
1907 ValueType value_type) { 1931 ValueType value_type,
1932 TransitionFlag flag) {
1908 ASSERT(!IsJSGlobalProxy()); 1933 ASSERT(!IsJSGlobalProxy());
1909 ASSERT(DescriptorArray::kNotFound == 1934 ASSERT(DescriptorArray::kNotFound ==
1910 map()->instance_descriptors()->Search( 1935 map()->instance_descriptors()->Search(
1911 name, map()->NumberOfOwnDescriptors())); 1936 name, map()->NumberOfOwnDescriptors()));
1912 1937
1913 // Normalize the object if the name is an actual name (not the 1938 // Normalize the object if the name is an actual name (not the
1914 // hidden strings) and is not a real identifier. 1939 // hidden strings) and is not a real identifier.
1915 // Normalize the object if it will have too many fast properties. 1940 // Normalize the object if it will have too many fast properties.
1916 Isolate* isolate = GetHeap()->isolate(); 1941 Isolate* isolate = GetHeap()->isolate();
1917 if ((!name->IsSymbol() && !IsIdentifier(isolate->unicode_cache(), name) 1942 if ((!name->IsSymbol() &&
1918 && name != isolate->heap()->hidden_string()) || 1943 !IsIdentifier(isolate->unicode_cache(), name) &&
1919 (map()->unused_property_fields() == 0 && 1944 name != isolate->heap()->hidden_string()) ||
1920 TooManyFastProperties(properties()->length(), store_mode))) { 1945 TooManyFastProperties(store_mode)) {
1921 Object* obj; 1946 MaybeObject* maybe_failure =
1922 MaybeObject* maybe_obj =
1923 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 1947 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1924 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1948 if (maybe_failure->IsFailure()) return maybe_failure;
1925
1926 return AddSlowProperty(name, value, attributes); 1949 return AddSlowProperty(name, value, attributes);
1927 } 1950 }
1928 1951
1929 // Compute the new index for new field. 1952 // Compute the new index for new field.
1930 int index = map()->NextFreePropertyIndex(); 1953 int index = map()->NextFreePropertyIndex();
1931 1954
1932 // Allocate new instance descriptors with (name, index) added 1955 // Allocate new instance descriptors with (name, index) added
1933 if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED; 1956 if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
1934 Representation representation = value->OptimalRepresentation(value_type); 1957 Representation representation = value->OptimalRepresentation(value_type);
1935 1958
1936 FieldDescriptor new_field(name, index, attributes, representation); 1959 FieldDescriptor new_field(name, index, attributes, representation);
1937 1960
1938 ASSERT(index < map()->inobject_properties() || 1961 ASSERT(index < map()->inobject_properties() ||
1939 (index - map()->inobject_properties()) < properties()->length() || 1962 (index - map()->inobject_properties()) < properties()->length() ||
1940 map()->unused_property_fields() == 0); 1963 map()->unused_property_fields() == 0);
1941 1964
1942 FixedArray* values = NULL; 1965 FixedArray* values = NULL;
1943 1966
1944 // TODO(verwaest): Merge with AddFastPropertyUsingMap. 1967 // TODO(verwaest): Merge with AddFastPropertyUsingMap.
1945 if (map()->unused_property_fields() == 0) { 1968 if (map()->unused_property_fields() == 0) {
1946 // Make room for the new value 1969 // Make room for the new value
1947 MaybeObject* maybe_values = 1970 MaybeObject* maybe_values =
1948 properties()->CopySize(properties()->length() + kFieldsAdded); 1971 properties()->CopySize(properties()->length() + kFieldsAdded);
1949 if (!maybe_values->To(&values)) return maybe_values; 1972 if (!maybe_values->To(&values)) return maybe_values;
1950 } 1973 }
1951 1974
1952 TransitionFlag flag = INSERT_TRANSITION;
1953
1954 Heap* heap = isolate->heap(); 1975 Heap* heap = isolate->heap();
1955 1976
1956 Object* storage; 1977 Object* storage;
1957 MaybeObject* maybe_storage = 1978 MaybeObject* maybe_storage =
1958 value->AllocateNewStorageFor(heap, representation); 1979 value->AllocateNewStorageFor(heap, representation);
1959 if (!maybe_storage->To(&storage)) return maybe_storage; 1980 if (!maybe_storage->To(&storage)) return maybe_storage;
1960 1981
1961 // Note that Map::CopyAddDescriptor has side-effects, the new map is already 1982 // Note that Map::CopyAddDescriptor has side-effects, the new map is already
1962 // inserted in the transition tree. No more allocations that might fail are 1983 // inserted in the transition tree. No more allocations that might fail are
1963 // allowed after this point. 1984 // allowed after this point.
(...skipping 12 matching lines...) Expand all
1976 set_map(new_map); 1997 set_map(new_map);
1977 1998
1978 FastPropertyAtPut(index, storage); 1999 FastPropertyAtPut(index, storage);
1979 return value; 2000 return value;
1980 } 2001 }
1981 2002
1982 2003
1983 MaybeObject* JSObject::AddConstantProperty( 2004 MaybeObject* JSObject::AddConstantProperty(
1984 Name* name, 2005 Name* name,
1985 Object* constant, 2006 Object* constant,
1986 PropertyAttributes attributes) { 2007 PropertyAttributes attributes,
2008 TransitionFlag initial_flag) {
1987 // Allocate new instance descriptors with (name, constant) added 2009 // Allocate new instance descriptors with (name, constant) added
1988 ConstantDescriptor d(name, constant, attributes); 2010 ConstantDescriptor d(name, constant, attributes);
1989 2011
1990 TransitionFlag flag = 2012 TransitionFlag flag =
1991 // Do not add transitions to global objects. 2013 // Do not add transitions to global objects.
1992 (IsGlobalObject() || 2014 (IsGlobalObject() ||
1993 // Don't add transitions to special properties with non-trivial 2015 // Don't add transitions to special properties with non-trivial
1994 // attributes. 2016 // attributes.
1995 attributes != NONE) 2017 attributes != NONE)
1996 ? OMIT_TRANSITION 2018 ? OMIT_TRANSITION
1997 : INSERT_TRANSITION; 2019 : initial_flag;
1998 2020
1999 Map* new_map; 2021 Map* new_map;
2000 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); 2022 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag);
2001 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 2023 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2002 2024
2003 set_map(new_map); 2025 set_map(new_map);
2004 return constant; 2026 return constant;
2005 } 2027 }
2006 2028
2007 2029
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2047 } 2069 }
2048 2070
2049 2071
2050 MaybeObject* JSObject::AddProperty(Name* name, 2072 MaybeObject* JSObject::AddProperty(Name* name,
2051 Object* value, 2073 Object* value,
2052 PropertyAttributes attributes, 2074 PropertyAttributes attributes,
2053 StrictModeFlag strict_mode, 2075 StrictModeFlag strict_mode,
2054 JSReceiver::StoreFromKeyed store_mode, 2076 JSReceiver::StoreFromKeyed store_mode,
2055 ExtensibilityCheck extensibility_check, 2077 ExtensibilityCheck extensibility_check,
2056 ValueType value_type, 2078 ValueType value_type,
2057 StoreMode mode) { 2079 StoreMode mode,
2080 TransitionFlag transition_flag) {
2058 ASSERT(!IsJSGlobalProxy()); 2081 ASSERT(!IsJSGlobalProxy());
2059 Map* map_of_this = map(); 2082 Map* map_of_this = map();
2060 Heap* heap = GetHeap(); 2083 Heap* heap = GetHeap();
2061 Isolate* isolate = heap->isolate(); 2084 Isolate* isolate = heap->isolate();
2062 MaybeObject* result; 2085 MaybeObject* result;
2063 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && 2086 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK &&
2064 !map_of_this->is_extensible()) { 2087 !map_of_this->is_extensible()) {
2065 if (strict_mode == kNonStrictMode) { 2088 if (strict_mode == kNonStrictMode) {
2066 return value; 2089 return value;
2067 } else { 2090 } else {
2068 Handle<Object> args[1] = {Handle<Name>(name)}; 2091 Handle<Object> args[1] = {Handle<Name>(name)};
2069 return isolate->Throw( 2092 return isolate->Throw(
2070 *isolate->factory()->NewTypeError("object_not_extensible", 2093 *isolate->factory()->NewTypeError("object_not_extensible",
2071 HandleVector(args, 1))); 2094 HandleVector(args, 1)));
2072 } 2095 }
2073 } 2096 }
2074 2097
2075 if (HasFastProperties()) { 2098 if (HasFastProperties()) {
2076 // Ensure the descriptor array does not get too big. 2099 // Ensure the descriptor array does not get too big.
2077 if (map_of_this->NumberOfOwnDescriptors() < 2100 if (map_of_this->NumberOfOwnDescriptors() <
2078 DescriptorArray::kMaxNumberOfDescriptors) { 2101 DescriptorArray::kMaxNumberOfDescriptors) {
2079 // TODO(verwaest): Support other constants. 2102 // TODO(verwaest): Support other constants.
2080 // if (mode == ALLOW_AS_CONSTANT && 2103 // if (mode == ALLOW_AS_CONSTANT &&
2081 // !value->IsTheHole() && 2104 // !value->IsTheHole() &&
2082 // !value->IsConsString()) { 2105 // !value->IsConsString()) {
2083 if (value->IsJSFunction()) { 2106 if (value->IsJSFunction()) {
2084 result = AddConstantProperty(name, value, attributes); 2107 result = AddConstantProperty(name, value, attributes, transition_flag);
2085 } else { 2108 } else {
2086 result = AddFastProperty( 2109 result = AddFastProperty(
2087 name, value, attributes, store_mode, value_type); 2110 name, value, attributes, store_mode, value_type, transition_flag);
2088 } 2111 }
2089 } else { 2112 } else {
2090 // Normalize the object to prevent very large instance descriptors. 2113 // Normalize the object to prevent very large instance descriptors.
2091 // This eliminates unwanted N^2 allocation and lookup behavior. 2114 // This eliminates unwanted N^2 allocation and lookup behavior.
2092 Object* obj; 2115 Object* obj;
2093 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2116 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2094 if (!maybe->To(&obj)) return maybe; 2117 if (!maybe->To(&obj)) return maybe;
2095 result = AddSlowProperty(name, value, attributes); 2118 result = AddSlowProperty(name, value, attributes);
2096 } 2119 }
2097 } else { 2120 } else {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 ASSERT(!threw); 2167 ASSERT(!threw);
2145 isolate->set_observer_delivery_pending(false); 2168 isolate->set_observer_delivery_pending(false);
2146 } 2169 }
2147 2170
2148 2171
2149 MaybeObject* JSObject::SetPropertyPostInterceptor( 2172 MaybeObject* JSObject::SetPropertyPostInterceptor(
2150 Name* name, 2173 Name* name,
2151 Object* value, 2174 Object* value,
2152 PropertyAttributes attributes, 2175 PropertyAttributes attributes,
2153 StrictModeFlag strict_mode, 2176 StrictModeFlag strict_mode,
2154 ExtensibilityCheck extensibility_check,
2155 StoreMode mode) { 2177 StoreMode mode) {
2156 // Check local property, ignore interceptor. 2178 // Check local property, ignore interceptor.
2157 LookupResult result(GetIsolate()); 2179 LookupResult result(GetIsolate());
2158 LocalLookupRealNamedProperty(name, &result); 2180 LocalLookupRealNamedProperty(name, &result);
2159 if (!result.IsFound()) map()->LookupTransition(this, name, &result); 2181 if (!result.IsFound()) map()->LookupTransition(this, name, &result);
2160 if (result.IsFound()) { 2182 if (result.IsFound()) {
2161 // An existing property or a map transition was found. Use set property to 2183 // An existing property or a map transition was found. Use set property to
2162 // handle all these cases. 2184 // handle all these cases.
2163 return SetProperty(&result, name, value, attributes, strict_mode); 2185 return SetProperty(&result, name, value, attributes, strict_mode);
2164 } 2186 }
2165 bool done = false; 2187 bool done = false;
2166 MaybeObject* result_object; 2188 MaybeObject* result_object =
2167 result_object =
2168 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); 2189 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done);
2169 if (done) return result_object; 2190 if (done) return result_object;
2170 // Add a new real property. 2191 // Add a new real property.
2171 return AddProperty(name, value, attributes, strict_mode, 2192 return AddProperty(name, value, attributes, strict_mode,
2172 MAY_BE_STORE_FROM_KEYED, extensibility_check, 2193 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK,
2173 OPTIMAL_REPRESENTATION, mode); 2194 OPTIMAL_REPRESENTATION, mode);
2174 } 2195 }
2175 2196
2176 2197
2177 MaybeObject* JSObject::ReplaceSlowProperty(Name* name, 2198 MaybeObject* JSObject::ReplaceSlowProperty(Name* name,
2178 Object* value, 2199 Object* value,
2179 PropertyAttributes attributes) { 2200 PropertyAttributes attributes) {
2180 NameDictionary* dictionary = property_dictionary(); 2201 NameDictionary* dictionary = property_dictionary();
2181 int old_index = dictionary->FindEntry(name); 2202 int old_index = dictionary->FindEntry(name);
2182 int new_enumeration_index = 0; // 0 means "Use the next available index." 2203 int new_enumeration_index = 0; // 0 means "Use the next available index."
2183 if (old_index != -1) { 2204 if (old_index != -1) {
2184 // All calls to ReplaceSlowProperty have had all transitions removed. 2205 // All calls to ReplaceSlowProperty have had all transitions removed.
2185 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); 2206 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index();
2186 } 2207 }
2187 2208
2188 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); 2209 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
2189 return SetNormalizedProperty(name, value, new_details); 2210 return SetNormalizedProperty(name, value, new_details);
2190 } 2211 }
2191 2212
2192 2213
2193 MaybeObject* JSObject::ConvertTransitionToMapTransition(
2194 int transition_index,
2195 Name* name,
2196 Object* new_value,
2197 PropertyAttributes attributes) {
2198 Map* old_map = map();
2199 Map* old_target = old_map->GetTransition(transition_index);
2200 Object* result;
2201
2202 MaybeObject* maybe_result = ConvertDescriptorToField(
2203 name, new_value, attributes, OMIT_TRANSITION_KEEP_REPRESENTATIONS);
2204 if (!maybe_result->To(&result)) return maybe_result;
2205
2206 if (!HasFastProperties()) return result;
2207
2208 // This method should only be used to convert existing transitions.
2209 Map* new_map = map();
2210
2211 // TODO(verwaest): From here on we lose existing map transitions, causing
2212 // invalid back pointers. This will change once we can store multiple
2213 // transitions with the same key.
2214 bool owned_descriptors = old_map->owns_descriptors();
2215 if (owned_descriptors ||
2216 old_target->instance_descriptors() == old_map->instance_descriptors()) {
2217 // Since the conversion above generated a new fast map with an additional
2218 // property which can be shared as well, install this descriptor pointer
2219 // along the entire chain of smaller maps.
2220 Map* map;
2221 DescriptorArray* new_descriptors = new_map->instance_descriptors();
2222 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2223 for (Object* current = old_map;
2224 !current->IsUndefined();
2225 current = map->GetBackPointer()) {
2226 map = Map::cast(current);
2227 if (map->instance_descriptors() != old_descriptors) break;
2228 map->SetEnumLength(Map::kInvalidEnumCache);
2229 map->set_instance_descriptors(new_descriptors);
2230 }
2231 old_map->set_owns_descriptors(false);
2232 }
2233
2234 old_target->DeprecateTransitionTree();
2235
2236 old_map->SetTransition(transition_index, new_map);
2237 new_map->SetBackPointer(old_map);
2238 return result;
2239 }
2240
2241
2242 MaybeObject* JSObject::ConvertDescriptorToField(Name* name,
2243 Object* new_value,
2244 PropertyAttributes attributes,
2245 TransitionFlag flag) {
2246 if (map()->unused_property_fields() == 0 &&
2247 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) {
2248 Object* obj;
2249 MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2250 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2251 return ReplaceSlowProperty(name, new_value, attributes);
2252 }
2253
2254 Representation representation = IsJSContextExtensionObject()
2255 ? Representation::Tagged() : new_value->OptimalRepresentation();
2256 int index = map()->NextFreePropertyIndex();
2257 FieldDescriptor new_field(name, index, attributes, representation);
2258
2259 // Make a new map for the object.
2260 Map* new_map;
2261 MaybeObject* maybe_new_map = map()->CopyInsertDescriptor(&new_field, flag);
2262 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2263
2264 // Make new properties array if necessary.
2265 FixedArray* new_properties = NULL;
2266 int new_unused_property_fields = map()->unused_property_fields() - 1;
2267 if (map()->unused_property_fields() == 0) {
2268 new_unused_property_fields = kFieldsAdded - 1;
2269 MaybeObject* maybe_new_properties =
2270 properties()->CopySize(properties()->length() + kFieldsAdded);
2271 if (!maybe_new_properties->To(&new_properties)) return maybe_new_properties;
2272 }
2273
2274 Heap* heap = GetHeap();
2275 Object* storage;
2276 MaybeObject* maybe_storage =
2277 new_value->AllocateNewStorageFor(heap, representation);
2278 if (!maybe_storage->To(&storage)) return maybe_storage;
2279
2280 // Update pointers to commit changes.
2281 // Object points to the new map.
2282 new_map->set_unused_property_fields(new_unused_property_fields);
2283 set_map(new_map);
2284 if (new_properties != NULL) {
2285 set_properties(new_properties);
2286 }
2287 FastPropertyAtPut(index, storage);
2288 return new_value;
2289 }
2290
2291
2292 const char* Representation::Mnemonic() const { 2214 const char* Representation::Mnemonic() const {
2293 switch (kind_) { 2215 switch (kind_) {
2294 case kNone: return "v"; 2216 case kNone: return "v";
2295 case kTagged: return "t"; 2217 case kTagged: return "t";
2296 case kSmi: return "s"; 2218 case kSmi: return "s";
2297 case kDouble: return "d"; 2219 case kDouble: return "d";
2298 case kInteger32: return "i"; 2220 case kInteger32: return "i";
2299 case kHeapObject: return "h"; 2221 case kHeapObject: return "h";
2300 case kExternal: return "x"; 2222 case kExternal: return "x";
2301 default: 2223 default:
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2428 if (!maybe_array->To(&array)) return maybe_array; 2350 if (!maybe_array->To(&array)) return maybe_array;
2429 2351
2430 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2352 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2431 DescriptorArray* new_descriptors = new_map->instance_descriptors(); 2353 DescriptorArray* new_descriptors = new_map->instance_descriptors();
2432 int descriptors = new_map->NumberOfOwnDescriptors(); 2354 int descriptors = new_map->NumberOfOwnDescriptors();
2433 2355
2434 for (int i = 0; i < descriptors; i++) { 2356 for (int i = 0; i < descriptors; i++) {
2435 PropertyDetails details = new_descriptors->GetDetails(i); 2357 PropertyDetails details = new_descriptors->GetDetails(i);
2436 if (details.type() != FIELD) continue; 2358 if (details.type() != FIELD) continue;
2437 PropertyDetails old_details = old_descriptors->GetDetails(i); 2359 PropertyDetails old_details = old_descriptors->GetDetails(i);
2360 if (old_details.type() == CALLBACKS) {
2361 ASSERT(details.representation().IsTagged());
2362 continue;
2363 }
2438 ASSERT(old_details.type() == CONSTANT || 2364 ASSERT(old_details.type() == CONSTANT ||
2439 old_details.type() == FIELD); 2365 old_details.type() == FIELD);
2440 Object* value = old_details.type() == CONSTANT 2366 Object* value = old_details.type() == CONSTANT
2441 ? old_descriptors->GetValue(i) 2367 ? old_descriptors->GetValue(i)
2442 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); 2368 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
2443 if (FLAG_track_double_fields && 2369 if (FLAG_track_double_fields &&
2444 !old_details.representation().IsDouble() && 2370 !old_details.representation().IsDouble() &&
2445 details.representation().IsDouble()) { 2371 details.representation().IsDouble()) {
2446 if (old_details.representation().IsNone()) value = Smi::FromInt(0); 2372 if (old_details.representation().IsNone()) value = Smi::FromInt(0);
2447 // Objects must be allocated in the old object space, since the 2373 // Objects must be allocated in the old object space, since the
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2484 } 2410 }
2485 2411
2486 set_map(new_map); 2412 set_map(new_map);
2487 2413
2488 return this; 2414 return this;
2489 } 2415 }
2490 2416
2491 2417
2492 MaybeObject* JSObject::GeneralizeFieldRepresentation( 2418 MaybeObject* JSObject::GeneralizeFieldRepresentation(
2493 int modify_index, 2419 int modify_index,
2494 Representation new_representation) { 2420 Representation new_representation,
2421 StoreMode store_mode) {
2495 Map* new_map; 2422 Map* new_map;
2496 MaybeObject* maybe_new_map = 2423 MaybeObject* maybe_new_map = map()->GeneralizeRepresentation(
2497 map()->GeneralizeRepresentation(modify_index, new_representation); 2424 modify_index, new_representation, store_mode);
2498 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 2425 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2499 if (map() == new_map) return this; 2426 if (map() == new_map) return this;
2500 2427
2501 return MigrateToMap(new_map); 2428 return MigrateToMap(new_map);
2502 } 2429 }
2503 2430
2504 2431
2505 int Map::NumberOfFields() { 2432 int Map::NumberOfFields() {
2506 DescriptorArray* descriptors = instance_descriptors(); 2433 DescriptorArray* descriptors = instance_descriptors();
2507 int result = 0; 2434 int result = 0;
2508 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { 2435 for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
2509 if (descriptors->GetDetails(i).type() == FIELD) result++; 2436 if (descriptors->GetDetails(i).type() == FIELD) result++;
2510 } 2437 }
2511 return result; 2438 return result;
2512 } 2439 }
2513 2440
2514 2441
2515 MaybeObject* Map::CopyGeneralizeAllRepresentations() { 2442 MaybeObject* Map::CopyGeneralizeAllRepresentations(
2443 int modify_index,
2444 StoreMode store_mode,
2445 PropertyAttributes attributes,
2446 const char* reason) {
2516 Map* new_map; 2447 Map* new_map;
2517 MaybeObject* maybe_map = this->Copy(); 2448 MaybeObject* maybe_map = this->Copy();
2518 if (!maybe_map->To(&new_map)) return maybe_map; 2449 if (!maybe_map->To(&new_map)) return maybe_map;
2519 2450
2520 new_map->instance_descriptors()->InitializeRepresentations( 2451 DescriptorArray* descriptors = new_map->instance_descriptors();
2521 Representation::Tagged()); 2452 descriptors->InitializeRepresentations(Representation::Tagged());
2453
2454 // Unless the instance is being migrated, ensure that modify_index is a field.
2455 PropertyDetails details = descriptors->GetDetails(modify_index);
2456 if (store_mode == FORCE_FIELD && details.type() != FIELD) {
2457 FieldDescriptor d(descriptors->GetKey(modify_index),
2458 new_map->NumberOfFields(),
2459 attributes,
2460 Representation::Tagged());
2461 d.SetSortedKeyIndex(details.pointer());
2462 descriptors->Set(modify_index, &d);
2463 int unused_property_fields = new_map->unused_property_fields() - 1;
2464 if (unused_property_fields < 0) {
2465 unused_property_fields += JSObject::kFieldsAdded;
2466 }
2467 new_map->set_unused_property_fields(unused_property_fields);
2468 }
2469
2522 if (FLAG_trace_generalization) { 2470 if (FLAG_trace_generalization) {
2523 PrintF("failed generalization %p -> %p\n", 2471 PrintGeneralization(stdout, reason, modify_index,
2524 static_cast<void*>(this), static_cast<void*>(new_map)); 2472 new_map->NumberOfOwnDescriptors(),
2473 new_map->NumberOfOwnDescriptors(),
2474 details.type() == CONSTANT && store_mode == FORCE_FIELD,
2475 Representation::Tagged(), Representation::Tagged());
2525 } 2476 }
2526 return new_map; 2477 return new_map;
2527 } 2478 }
2528 2479
2529 2480
2530 void Map::DeprecateTransitionTree() { 2481 void Map::DeprecateTransitionTree() {
2531 if (!FLAG_track_fields) return; 2482 if (!FLAG_track_fields) return;
2532 if (is_deprecated()) return; 2483 if (is_deprecated()) return;
2533 if (HasTransitionArray()) { 2484 if (HasTransitionArray()) {
2534 TransitionArray* transitions = this->transitions(); 2485 TransitionArray* transitions = this->transitions();
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
2659 // walk the transition tree. 2610 // walk the transition tree.
2660 // - Merge/generalize the descriptor array of the current map and |updated|. 2611 // - Merge/generalize the descriptor array of the current map and |updated|.
2661 // - Generalize the |modify_index| descriptor using |new_representation|. 2612 // - Generalize the |modify_index| descriptor using |new_representation|.
2662 // - Walk the tree again starting from the root towards |updated|. Stop at 2613 // - Walk the tree again starting from the root towards |updated|. Stop at
2663 // |split_map|, the first map who's descriptor array does not match the merged 2614 // |split_map|, the first map who's descriptor array does not match the merged
2664 // descriptor array. 2615 // descriptor array.
2665 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. 2616 // - If |updated| == |split_map|, |updated| is in the expected state. Return it.
2666 // - Otherwise, invalidate the outdated transition target from |updated|, and 2617 // - Otherwise, invalidate the outdated transition target from |updated|, and
2667 // replace its transition tree with a new branch for the updated descriptors. 2618 // replace its transition tree with a new branch for the updated descriptors.
2668 MaybeObject* Map::GeneralizeRepresentation(int modify_index, 2619 MaybeObject* Map::GeneralizeRepresentation(int modify_index,
2669 Representation new_representation) { 2620 Representation new_representation,
2621 StoreMode store_mode) {
2670 Map* old_map = this; 2622 Map* old_map = this;
2671 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2623 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2672 Representation old_representation = 2624 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2673 old_descriptors->GetDetails(modify_index).representation(); 2625 Representation old_representation = old_details.representation();
2674 2626
2675 // It's fine to transition from None to anything but double without any 2627 // It's fine to transition from None to anything but double without any
2676 // modification to the object, because the default uninitialized value for 2628 // modification to the object, because the default uninitialized value for
2677 // representation None can be overwritten by both smi and tagged values. 2629 // representation None can be overwritten by both smi and tagged values.
2678 // Doubles, however, would require a box allocation. 2630 // Doubles, however, would require a box allocation.
2679 if (old_representation.IsNone() && 2631 if (old_representation.IsNone() &&
2680 !new_representation.IsNone() && 2632 !new_representation.IsNone() &&
2681 !new_representation.IsDouble()) { 2633 !new_representation.IsDouble()) {
2682 old_descriptors->SetRepresentation(modify_index, new_representation); 2634 old_descriptors->SetRepresentation(modify_index, new_representation);
2683 return old_map; 2635 return old_map;
2684 } 2636 }
2685 2637
2686 int descriptors = old_map->NumberOfOwnDescriptors(); 2638 int descriptors = old_map->NumberOfOwnDescriptors();
2687 Map* root_map = old_map->FindRootMap(); 2639 Map* root_map = old_map->FindRootMap();
2688 2640
2689 // Check the state of the root map. 2641 // Check the state of the root map.
2690 if (!old_map->EquivalentToForTransition(root_map)) { 2642 if (!old_map->EquivalentToForTransition(root_map)) {
2691 return CopyGeneralizeAllRepresentations(); 2643 return CopyGeneralizeAllRepresentations(
2644 modify_index, store_mode, old_details.attributes(), "not equivalent");
2692 } 2645 }
2693 2646
2694 int verbatim = root_map->NumberOfOwnDescriptors(); 2647 int verbatim = root_map->NumberOfOwnDescriptors();
2695 2648
2649 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
2650 return CopyGeneralizeAllRepresentations(
2651 modify_index, store_mode,
2652 old_details.attributes(), "root modification");
2653 }
2654
2696 Map* updated = root_map->FindUpdatedMap( 2655 Map* updated = root_map->FindUpdatedMap(
2697 verbatim, descriptors, old_descriptors); 2656 verbatim, descriptors, old_descriptors);
2698 if (updated == NULL) return CopyGeneralizeAllRepresentations(); 2657 if (updated == NULL) {
2658 return CopyGeneralizeAllRepresentations(
2659 modify_index, store_mode, old_details.attributes(), "incompatible");
2660 }
2699 2661
2700 DescriptorArray* updated_descriptors = updated->instance_descriptors(); 2662 DescriptorArray* updated_descriptors = updated->instance_descriptors();
2701 2663
2702 int valid = updated->NumberOfOwnDescriptors(); 2664 int valid = updated->NumberOfOwnDescriptors();
2665
2666 // Directly change the map if the target map is more general. Ensure that the
2667 // target type of the modify_index is a FIELD, unless we are migrating.
2703 if (updated_descriptors->IsMoreGeneralThan( 2668 if (updated_descriptors->IsMoreGeneralThan(
2704 verbatim, valid, descriptors, old_descriptors)) { 2669 verbatim, valid, descriptors, old_descriptors) &&
2670 (store_mode == ALLOW_AS_CONSTANT ||
2671 updated_descriptors->GetDetails(modify_index).type() == FIELD)) {
2705 Representation updated_representation = 2672 Representation updated_representation =
2706 updated_descriptors->GetDetails(modify_index).representation(); 2673 updated_descriptors->GetDetails(modify_index).representation();
2707 if (new_representation.fits_into(updated_representation)) { 2674 if (new_representation.fits_into(updated_representation)) return updated;
2708 if (FLAG_trace_generalization &&
2709 !(modify_index == 0 && new_representation.IsNone())) {
2710 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2711 PrintGeneralization(stdout, modify_index, descriptors, descriptors,
2712 old_details.representation(),
2713 updated_representation);
2714 }
2715 return updated;
2716 }
2717 } 2675 }
2718 2676
2719 DescriptorArray* new_descriptors; 2677 DescriptorArray* new_descriptors;
2720 MaybeObject* maybe_descriptors = updated_descriptors->Merge( 2678 MaybeObject* maybe_descriptors = updated_descriptors->Merge(
2721 verbatim, valid, descriptors, old_descriptors); 2679 verbatim, valid, descriptors, modify_index, store_mode, old_descriptors);
2722 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 2680 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
2681 ASSERT(store_mode == ALLOW_AS_CONSTANT ||
2682 new_descriptors->GetDetails(modify_index).type() == FIELD);
2723 2683
2724 old_representation = 2684 old_representation =
2725 new_descriptors->GetDetails(modify_index).representation(); 2685 new_descriptors->GetDetails(modify_index).representation();
2726 Representation updated_representation = 2686 Representation updated_representation =
2727 new_representation.generalize(old_representation); 2687 new_representation.generalize(old_representation);
2728 if (!updated_representation.Equals(old_representation)) { 2688 if (!updated_representation.Equals(old_representation)) {
2729 new_descriptors->SetRepresentation(modify_index, updated_representation); 2689 new_descriptors->SetRepresentation(modify_index, updated_representation);
2730 } 2690 }
2731 2691
2732 Map* split_map = root_map->FindLastMatchMap( 2692 Map* split_map = root_map->FindLastMatchMap(
2733 verbatim, descriptors, new_descriptors); 2693 verbatim, descriptors, new_descriptors);
2734 2694
2735 int split_descriptors = split_map->NumberOfOwnDescriptors(); 2695 int split_descriptors = split_map->NumberOfOwnDescriptors();
2736 // This is shadowed by |updated_descriptors| being more general than 2696 // This is shadowed by |updated_descriptors| being more general than
2737 // |old_descriptors|. 2697 // |old_descriptors|.
2738 ASSERT(descriptors != split_descriptors); 2698 ASSERT(descriptors != split_descriptors);
2739 2699
2740 int descriptor = split_descriptors; 2700 int descriptor = split_descriptors;
2741 split_map->DeprecateTarget( 2701 split_map->DeprecateTarget(
2742 old_descriptors->GetKey(descriptor), new_descriptors); 2702 old_descriptors->GetKey(descriptor), new_descriptors);
2743 2703
2744 if (FLAG_trace_generalization && 2704 if (FLAG_trace_generalization) {
2745 !(modify_index == 0 && new_representation.IsNone())) { 2705 PrintGeneralization(
2746 PrintGeneralization(stdout, modify_index, descriptor, descriptors, 2706 stdout, "", modify_index, descriptor, descriptors,
2747 old_representation, updated_representation); 2707 old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
2708 store_mode == FORCE_FIELD,
2709 old_representation, updated_representation);
2748 } 2710 }
2749 2711
2750 Map* new_map = split_map; 2712 Map* new_map = split_map;
2751 // Add missing transitions. 2713 // Add missing transitions.
2752 for (; descriptor < descriptors; descriptor++) { 2714 for (; descriptor < descriptors; descriptor++) {
2753 MaybeObject* maybe_map = new_map->CopyInstallDescriptors( 2715 MaybeObject* maybe_map = new_map->CopyInstallDescriptors(
2754 descriptor, new_descriptors); 2716 descriptor, new_descriptors);
2755 if (!maybe_map->To(&new_map)) { 2717 if (!maybe_map->To(&new_map)) {
2756 // Create a handle for the last created map to ensure it stays alive 2718 // Create a handle for the last created map to ensure it stays alive
2757 // during GC. Its descriptor array is too large, but it will be 2719 // during GC. Its descriptor array is too large, but it will be
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2804 if (name->IsSymbol()) return value; 2766 if (name->IsSymbol()) return value;
2805 Isolate* isolate = GetIsolate(); 2767 Isolate* isolate = GetIsolate();
2806 HandleScope scope(isolate); 2768 HandleScope scope(isolate);
2807 Handle<JSObject> this_handle(this); 2769 Handle<JSObject> this_handle(this);
2808 Handle<String> name_handle(String::cast(name)); 2770 Handle<String> name_handle(String::cast(name));
2809 Handle<Object> value_handle(value, isolate); 2771 Handle<Object> value_handle(value, isolate);
2810 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); 2772 Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
2811 if (!interceptor->setter()->IsUndefined()) { 2773 if (!interceptor->setter()->IsUndefined()) {
2812 LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name)); 2774 LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name));
2813 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); 2775 PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
2814 v8::NamedPropertySetter setter = 2776 v8::NamedPropertySetterCallback setter =
2815 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); 2777 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
2816 Handle<Object> value_unhole(value->IsTheHole() ? 2778 Handle<Object> value_unhole(value->IsTheHole() ?
2817 isolate->heap()->undefined_value() : 2779 isolate->heap()->undefined_value() :
2818 value, 2780 value,
2819 isolate); 2781 isolate);
2820 v8::Handle<v8::Value> result = args.Call(setter, 2782 v8::Handle<v8::Value> result = args.Call(setter,
2821 v8::Utils::ToLocal(name_handle), 2783 v8::Utils::ToLocal(name_handle),
2822 v8::Utils::ToLocal(value_unhole)); 2784 v8::Utils::ToLocal(value_unhole));
2823 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2785 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2824 if (!result.IsEmpty()) return *value_handle; 2786 if (!result.IsEmpty()) return *value_handle;
2825 } 2787 }
2826 MaybeObject* raw_result = 2788 MaybeObject* raw_result =
2827 this_handle->SetPropertyPostInterceptor(*name_handle, 2789 this_handle->SetPropertyPostInterceptor(*name_handle,
2828 *value_handle, 2790 *value_handle,
2829 attributes, 2791 attributes,
2830 strict_mode, 2792 strict_mode);
2831 PERFORM_EXTENSIBILITY_CHECK);
2832 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2793 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2833 return raw_result; 2794 return raw_result;
2834 } 2795 }
2835 2796
2836 2797
2837 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, 2798 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
2838 Handle<Name> key, 2799 Handle<Name> key,
2839 Handle<Object> value, 2800 Handle<Object> value,
2840 PropertyAttributes attributes, 2801 PropertyAttributes attributes,
2841 StrictModeFlag strict_mode) { 2802 StrictModeFlag strict_mode) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2907 Handle<Object> args[2] = { name_handle, receiver_handle }; 2868 Handle<Object> args[2] = { name_handle, receiver_handle };
2908 Handle<Object> error = 2869 Handle<Object> error =
2909 isolate->factory()->NewTypeError("incompatible_method_receiver", 2870 isolate->factory()->NewTypeError("incompatible_method_receiver",
2910 HandleVector(args, 2871 HandleVector(args,
2911 ARRAY_SIZE(args))); 2872 ARRAY_SIZE(args)));
2912 return isolate->Throw(*error); 2873 return isolate->Throw(*error);
2913 } 2874 }
2914 // TODO(rossberg): Support symbols in the API. 2875 // TODO(rossberg): Support symbols in the API.
2915 if (name->IsSymbol()) return value; 2876 if (name->IsSymbol()) return value;
2916 Object* call_obj = data->setter(); 2877 Object* call_obj = data->setter();
2917 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); 2878 v8::AccessorSetterCallback call_fun =
2879 v8::ToCData<v8::AccessorSetterCallback>(call_obj);
2918 if (call_fun == NULL) return value; 2880 if (call_fun == NULL) return value;
2919 Handle<String> key(String::cast(name)); 2881 Handle<String> key(String::cast(name));
2920 LOG(isolate, ApiNamedPropertyAccess("store", this, name)); 2882 LOG(isolate, ApiNamedPropertyAccess("store", this, name));
2921 PropertyCallbackArguments args( 2883 PropertyCallbackArguments args(
2922 isolate, data->data(), this, JSObject::cast(holder)); 2884 isolate, data->data(), this, JSObject::cast(holder));
2923 args.Call(call_fun, 2885 args.Call(call_fun,
2924 v8::Utils::ToLocal(key), 2886 v8::Utils::ToLocal(key),
2925 v8::Utils::ToLocal(value_handle)); 2887 v8::Utils::ToLocal(value_handle));
2926 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2888 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2927 return *value_handle; 2889 return *value_handle;
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
3394 Object* obj = result->GetCallbackObject(); 3356 Object* obj = result->GetCallbackObject();
3395 if (obj->IsAccessorInfo()) { 3357 if (obj->IsAccessorInfo()) {
3396 AccessorInfo* info = AccessorInfo::cast(obj); 3358 AccessorInfo* info = AccessorInfo::cast(obj);
3397 if (info->all_can_write()) { 3359 if (info->all_can_write()) {
3398 return SetPropertyWithCallback(result->GetCallbackObject(), 3360 return SetPropertyWithCallback(result->GetCallbackObject(),
3399 name, 3361 name,
3400 value, 3362 value,
3401 result->holder(), 3363 result->holder(),
3402 strict_mode); 3364 strict_mode);
3403 } 3365 }
3366 } else if (obj->IsAccessorPair()) {
3367 AccessorPair* pair = AccessorPair::cast(obj);
3368 if (pair->all_can_read()) {
3369 return SetPropertyWithCallback(result->GetCallbackObject(),
3370 name,
3371 value,
3372 result->holder(),
3373 strict_mode);
3374 }
3404 } 3375 }
3405 break; 3376 break;
3406 } 3377 }
3407 case INTERCEPTOR: { 3378 case INTERCEPTOR: {
3408 // Try lookup real named properties. Note that only property can be 3379 // Try lookup real named properties. Note that only property can be
3409 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. 3380 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain.
3410 LookupResult r(GetIsolate()); 3381 LookupResult r(GetIsolate());
3411 LookupRealNamedProperty(name, &r); 3382 LookupRealNamedProperty(name, &r);
3412 if (r.IsProperty()) { 3383 if (r.IsProperty()) {
3413 return SetPropertyWithFailedAccessCheck(&r, 3384 return SetPropertyWithFailedAccessCheck(&r,
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
3775 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { 3746 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
3776 CALL_HEAP_FUNCTION( 3747 CALL_HEAP_FUNCTION(
3777 object->GetIsolate(), 3748 object->GetIsolate(),
3778 object->MigrateInstance(), 3749 object->MigrateInstance(),
3779 Object); 3750 Object);
3780 } 3751 }
3781 3752
3782 3753
3783 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map, 3754 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map,
3784 int modify_index, 3755 int modify_index,
3785 Representation representation) { 3756 Representation representation,
3757 StoreMode store_mode) {
3786 CALL_HEAP_FUNCTION( 3758 CALL_HEAP_FUNCTION(
3787 map->GetIsolate(), 3759 map->GetIsolate(),
3788 map->GeneralizeRepresentation(modify_index, representation), 3760 map->GeneralizeRepresentation(modify_index, representation, store_mode),
3789 Map); 3761 Map);
3790 } 3762 }
3791 3763
3792 3764
3765 static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup,
3766 Handle<Name> name,
3767 Handle<Object> value,
3768 PropertyAttributes attributes) {
3769 Map* transition_map = lookup->GetTransitionTarget();
3770 int descriptor = transition_map->LastAdded();
3771
3772 DescriptorArray* descriptors = transition_map->instance_descriptors();
3773 PropertyDetails details = descriptors->GetDetails(descriptor);
3774
3775 if (details.type() == CALLBACKS || attributes != details.attributes()) {
3776 // AddProperty will either normalize the object, or create a new fast copy
3777 // of the map. If we get a fast copy of the map, all field representations
3778 // will be tagged since the transition is omitted.
3779 return lookup->holder()->AddProperty(
3780 *name, *value, attributes, kNonStrictMode,
3781 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
3782 JSReceiver::OMIT_EXTENSIBILITY_CHECK,
3783 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
3784 }
3785
3786 // Keep the target CONSTANT if the same value is stored.
3787 // TODO(verwaest): Also support keeping the placeholder
3788 // (value->IsUninitialized) as constant.
3789 if (details.type() == CONSTANT &&
3790 descriptors->GetValue(descriptor) == *value) {
3791 lookup->holder()->set_map(transition_map);
3792 return *value;
3793 }
3794
3795 Representation representation = details.representation();
3796
3797 if (!value->FitsRepresentation(representation) ||
3798 details.type() == CONSTANT) {
3799 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
3800 descriptor, value->OptimalRepresentation(), FORCE_FIELD);
3801 if (!maybe_map->To(&transition_map)) return maybe_map;
3802 Object* back = transition_map->GetBackPointer();
3803 if (back->IsMap()) {
3804 MaybeObject* maybe_failure =
3805 lookup->holder()->MigrateToMap(Map::cast(back));
3806 if (maybe_failure->IsFailure()) return maybe_failure;
3807 }
3808 descriptors = transition_map->instance_descriptors();
3809 representation = descriptors->GetDetails(descriptor).representation();
3810 }
3811
3812 int field_index = descriptors->GetFieldIndex(descriptor);
3813 return lookup->holder()->AddFastPropertyUsingMap(
3814 transition_map, *name, *value, field_index, representation);
3815 }
3816
3817
3818 static MaybeObject* SetPropertyToField(LookupResult* lookup,
3819 Handle<Name> name,
3820 Handle<Object> value) {
3821 Representation representation = lookup->representation();
3822 if (!value->FitsRepresentation(representation) ||
3823 lookup->type() == CONSTANT) {
3824 MaybeObject* maybe_failure =
3825 lookup->holder()->GeneralizeFieldRepresentation(
3826 lookup->GetDescriptorIndex(),
3827 value->OptimalRepresentation(),
3828 FORCE_FIELD);
3829 if (maybe_failure->IsFailure()) return maybe_failure;
3830 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3831 int descriptor = lookup->GetDescriptorIndex();
3832 representation = desc->GetDetails(descriptor).representation();
3833 }
3834
3835 if (FLAG_track_double_fields && representation.IsDouble()) {
3836 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
3837 lookup->GetFieldIndex().field_index()));
3838 storage->set_value(value->Number());
3839 return *value;
3840 }
3841
3842 lookup->holder()->FastPropertyAtPut(
3843 lookup->GetFieldIndex().field_index(), *value);
3844 return *value;
3845 }
3846
3847
3848 static MaybeObject* ConvertAndSetLocalProperty(LookupResult* lookup,
3849 Name* name,
3850 Object* value,
3851 PropertyAttributes attributes) {
3852 JSObject* object = lookup->holder();
3853 if (object->TooManyFastProperties()) {
3854 MaybeObject* maybe_failure = object->NormalizeProperties(
3855 CLEAR_INOBJECT_PROPERTIES, 0);
3856 if (maybe_failure->IsFailure()) return maybe_failure;
3857 }
3858
3859 if (!object->HasFastProperties()) {
3860 return object->ReplaceSlowProperty(name, value, attributes);
3861 }
3862
3863 int descriptor_index = lookup->GetDescriptorIndex();
3864 if (lookup->GetAttributes() == attributes) {
3865 MaybeObject* maybe_failure = object->GeneralizeFieldRepresentation(
3866 descriptor_index, Representation::Tagged(), FORCE_FIELD);
3867 if (maybe_failure->IsFailure()) return maybe_failure;
3868 } else {
3869 Map* map;
3870 MaybeObject* maybe_map = object->map()->CopyGeneralizeAllRepresentations(
3871 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch");
3872 if (!maybe_map->To(&map)) return maybe_map;
3873 MaybeObject* maybe_failure = object->MigrateToMap(map);
3874 if (maybe_failure->IsFailure()) return maybe_failure;
3875 }
3876
3877 DescriptorArray* descriptors = object->map()->instance_descriptors();
3878 int index = descriptors->GetDetails(descriptor_index).field_index();
3879 object->FastPropertyAtPut(index, value);
3880 return value;
3881 }
3882
3883
3884 static MaybeObject* SetPropertyToFieldWithAttributes(
3885 LookupResult* lookup,
3886 Handle<Name> name,
3887 Handle<Object> value,
3888 PropertyAttributes attributes) {
3889 if (lookup->GetAttributes() == attributes) {
3890 if (value->IsUninitialized()) return *value;
3891 return SetPropertyToField(lookup, name, value);
3892 } else {
3893 return ConvertAndSetLocalProperty(lookup, *name, *value, attributes);
3894 }
3895 }
3896
3897
3793 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, 3898 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
3794 Name* name_raw, 3899 Name* name_raw,
3795 Object* value_raw, 3900 Object* value_raw,
3796 PropertyAttributes attributes, 3901 PropertyAttributes attributes,
3797 StrictModeFlag strict_mode, 3902 StrictModeFlag strict_mode,
3798 StoreFromKeyed store_mode) { 3903 StoreFromKeyed store_mode) {
3799 Heap* heap = GetHeap(); 3904 Heap* heap = GetHeap();
3800 Isolate* isolate = heap->isolate(); 3905 Isolate* isolate = heap->isolate();
3801 // Make sure that the top context does not change when doing callbacks or 3906 // Make sure that the top context does not change when doing callbacks or
3802 // interceptor calls. 3907 // interceptor calls.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3871 old_value = Object::GetProperty(self, name); 3976 old_value = Object::GetProperty(self, name);
3872 } 3977 }
3873 3978
3874 // This is a real property that is not read-only, or it is a 3979 // This is a real property that is not read-only, or it is a
3875 // transition or null descriptor and there are no setters in the prototypes. 3980 // transition or null descriptor and there are no setters in the prototypes.
3876 MaybeObject* result = *value; 3981 MaybeObject* result = *value;
3877 switch (lookup->type()) { 3982 switch (lookup->type()) {
3878 case NORMAL: 3983 case NORMAL:
3879 result = lookup->holder()->SetNormalizedProperty(lookup, *value); 3984 result = lookup->holder()->SetNormalizedProperty(lookup, *value);
3880 break; 3985 break;
3881 case FIELD: { 3986 case FIELD:
3882 Representation representation = lookup->representation(); 3987 result = SetPropertyToField(lookup, name, value);
3883 if (!value->FitsRepresentation(representation)) {
3884 MaybeObject* maybe_failure =
3885 lookup->holder()->GeneralizeFieldRepresentation(
3886 lookup->GetDescriptorIndex(), value->OptimalRepresentation());
3887 if (maybe_failure->IsFailure()) return maybe_failure;
3888 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3889 int descriptor = lookup->GetDescriptorIndex();
3890 representation = desc->GetDetails(descriptor).representation();
3891 }
3892 if (FLAG_track_double_fields && representation.IsDouble()) {
3893 HeapNumber* storage =
3894 HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
3895 lookup->GetFieldIndex().field_index()));
3896 storage->set_value(value->Number());
3897 result = *value;
3898 break;
3899 }
3900 lookup->holder()->FastPropertyAtPut(
3901 lookup->GetFieldIndex().field_index(), *value);
3902 result = *value;
3903 break; 3988 break;
3904 }
3905 case CONSTANT: 3989 case CONSTANT:
3906 // Only replace the constant if necessary. 3990 // Only replace the constant if necessary.
3907 if (*value == lookup->GetConstant()) return *value; 3991 if (*value == lookup->GetConstant()) return *value;
3908 // Preserve the attributes of this existing property. 3992 result = SetPropertyToField(lookup, name, value);
3909 attributes = lookup->GetAttributes();
3910 result = lookup->holder()->ConvertDescriptorToField(
3911 *name, *value, attributes);
3912 break; 3993 break;
3913 case CALLBACKS: { 3994 case CALLBACKS: {
3914 Object* callback_object = lookup->GetCallbackObject(); 3995 Object* callback_object = lookup->GetCallbackObject();
3915 return self->SetPropertyWithCallback( 3996 return self->SetPropertyWithCallback(
3916 callback_object, *name, *value, lookup->holder(), strict_mode); 3997 callback_object, *name, *value, lookup->holder(), strict_mode);
3917 } 3998 }
3918 case INTERCEPTOR: 3999 case INTERCEPTOR:
3919 result = lookup->holder()->SetPropertyWithInterceptor( 4000 result = lookup->holder()->SetPropertyWithInterceptor(
3920 *name, *value, attributes, strict_mode); 4001 *name, *value, attributes, strict_mode);
3921 break; 4002 break;
3922 case TRANSITION: { 4003 case TRANSITION: {
3923 Map* transition_map = lookup->GetTransitionTarget(); 4004 result = SetPropertyUsingTransition(lookup, name, value, attributes);
3924 int descriptor = transition_map->LastAdded();
3925
3926 DescriptorArray* descriptors = transition_map->instance_descriptors();
3927 PropertyDetails details = descriptors->GetDetails(descriptor);
3928
3929 if (details.type() == FIELD) {
3930 if (attributes == details.attributes()) {
3931 Representation representation = details.representation();
3932 if (!value->FitsRepresentation(representation)) {
3933 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
3934 descriptor, value->OptimalRepresentation());
3935 if (!maybe_map->To(&transition_map)) return maybe_map;
3936 Object* back = transition_map->GetBackPointer();
3937 if (back->IsMap()) {
3938 MaybeObject* maybe_failure =
3939 lookup->holder()->MigrateToMap(Map::cast(back));
3940 if (maybe_failure->IsFailure()) return maybe_failure;
3941 }
3942 DescriptorArray* desc = transition_map->instance_descriptors();
3943 int descriptor = transition_map->LastAdded();
3944 representation = desc->GetDetails(descriptor).representation();
3945 }
3946 int field_index = descriptors->GetFieldIndex(descriptor);
3947 result = lookup->holder()->AddFastPropertyUsingMap(
3948 transition_map, *name, *value, field_index, representation);
3949 } else {
3950 result = lookup->holder()->ConvertDescriptorToField(
3951 *name, *value, attributes);
3952 }
3953 } else if (details.type() == CALLBACKS) {
3954 result = lookup->holder()->ConvertDescriptorToField(
3955 *name, *value, attributes);
3956 } else {
3957 ASSERT(details.type() == CONSTANT);
3958
3959 Object* constant = descriptors->GetValue(descriptor);
3960 if (constant == *value) {
3961 // If the same constant function is being added we can simply
3962 // transition to the target map.
3963 lookup->holder()->set_map(transition_map);
3964 result = constant;
3965 } else {
3966 // Otherwise, replace with a map transition to a new map with a FIELD,
3967 // even if the value is a constant function.
3968 result = lookup->holder()->ConvertTransitionToMapTransition(
3969 lookup->GetTransitionIndex(), *name, *value, attributes);
3970 }
3971 }
3972 break; 4005 break;
3973 } 4006 }
3974 case HANDLER: 4007 case HANDLER:
3975 case NONEXISTENT: 4008 case NONEXISTENT:
3976 UNREACHABLE(); 4009 UNREACHABLE();
3977 } 4010 }
3978 4011
3979 Handle<Object> hresult; 4012 Handle<Object> hresult;
3980 if (!result->ToHandle(&hresult, isolate)) return result; 4013 if (!result->ToHandle(&hresult, isolate)) return result;
3981 4014
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4020 *key, *value, attributes, value_type, mode), 4053 *key, *value, attributes, value_type, mode),
4021 Object); 4054 Object);
4022 } 4055 }
4023 4056
4024 4057
4025 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( 4058 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
4026 Name* name_raw, 4059 Name* name_raw,
4027 Object* value_raw, 4060 Object* value_raw,
4028 PropertyAttributes attributes, 4061 PropertyAttributes attributes,
4029 ValueType value_type, 4062 ValueType value_type,
4030 StoreMode mode) { 4063 StoreMode mode,
4064 ExtensibilityCheck extensibility_check) {
4031 // Make sure that the top context does not change when doing callbacks or 4065 // Make sure that the top context does not change when doing callbacks or
4032 // interceptor calls. 4066 // interceptor calls.
4033 AssertNoContextChange ncc; 4067 AssertNoContextChange ncc;
4034 Isolate* isolate = GetIsolate(); 4068 Isolate* isolate = GetIsolate();
4035 LookupResult lookup(isolate); 4069 LookupResult lookup(isolate);
4036 LocalLookup(name_raw, &lookup, true); 4070 LocalLookup(name_raw, &lookup, true);
4037 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); 4071 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup);
4038 // Check access rights if needed. 4072 // Check access rights if needed.
4039 if (IsAccessCheckNeeded()) { 4073 if (IsAccessCheckNeeded()) {
4040 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { 4074 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) {
4041 return SetPropertyWithFailedAccessCheck(&lookup, 4075 return SetPropertyWithFailedAccessCheck(&lookup,
4042 name_raw, 4076 name_raw,
4043 value_raw, 4077 value_raw,
4044 false, 4078 false,
4045 kNonStrictMode); 4079 kNonStrictMode);
4046 } 4080 }
4047 } 4081 }
4048 4082
4049 if (IsJSGlobalProxy()) { 4083 if (IsJSGlobalProxy()) {
4050 Object* proto = GetPrototype(); 4084 Object* proto = GetPrototype();
4051 if (proto->IsNull()) return value_raw; 4085 if (proto->IsNull()) return value_raw;
4052 ASSERT(proto->IsJSGlobalObject()); 4086 ASSERT(proto->IsJSGlobalObject());
4053 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( 4087 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes(
4054 name_raw, 4088 name_raw,
4055 value_raw, 4089 value_raw,
4056 attributes, 4090 attributes,
4057 value_type, 4091 value_type,
4058 mode); 4092 mode,
4093 extensibility_check);
4059 } 4094 }
4060 4095
4061 // Check for accessor in prototype chain removed here in clone. 4096 // Check for accessor in prototype chain removed here in clone.
4062 if (!lookup.IsFound()) { 4097 if (!lookup.IsFound()) {
4063 // Neither properties nor transitions found. 4098 // Neither properties nor transitions found.
4064 return AddProperty( 4099 return AddProperty(
4065 name_raw, value_raw, attributes, kNonStrictMode, 4100 name_raw, value_raw, attributes, kNonStrictMode,
4066 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, value_type, mode); 4101 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode);
4067 } 4102 }
4068 4103
4069 // From this point on everything needs to be handlified. 4104 // From this point on everything needs to be handlified.
4070 HandleScope scope(isolate); 4105 HandleScope scope(isolate);
4071 Handle<JSObject> self(this); 4106 Handle<JSObject> self(this);
4072 Handle<Name> name(name_raw); 4107 Handle<Name> name(name_raw);
4073 Handle<Object> value(value_raw, isolate); 4108 Handle<Object> value(value_raw, isolate);
4074 4109
4075 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); 4110 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate);
4076 PropertyAttributes old_attributes = ABSENT; 4111 PropertyAttributes old_attributes = ABSENT;
4077 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); 4112 bool is_observed = FLAG_harmony_observation && self->map()->is_observed();
4078 if (is_observed && lookup.IsProperty()) { 4113 if (is_observed && lookup.IsProperty()) {
4079 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name); 4114 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name);
4080 old_attributes = lookup.GetAttributes(); 4115 old_attributes = lookup.GetAttributes();
4081 } 4116 }
4082 4117
4083 // Check of IsReadOnly removed from here in clone. 4118 // Check of IsReadOnly removed from here in clone.
4084 MaybeObject* result = *value; 4119 MaybeObject* result = *value;
4085 switch (lookup.type()) { 4120 switch (lookup.type()) {
4086 case NORMAL: { 4121 case NORMAL:
4087 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); 4122 result = self->ReplaceSlowProperty(*name, *value, attributes);
4088 result = self->SetNormalizedProperty(*name, *value, details);
4089 break; 4123 break;
4090 } 4124 case FIELD:
4091 case FIELD: { 4125 result = SetPropertyToFieldWithAttributes(
4092 Representation representation = lookup.representation(); 4126 &lookup, name, value, attributes);
4093 Representation value_representation =
4094 value->OptimalRepresentation(value_type);
4095 if (value_representation.IsNone()) break;
4096 if (!value_representation.fits_into(representation)) {
4097 MaybeObject* maybe_failure = self->GeneralizeFieldRepresentation(
4098 lookup.GetDescriptorIndex(), value_representation);
4099 if (maybe_failure->IsFailure()) return maybe_failure;
4100 DescriptorArray* desc = self->map()->instance_descriptors();
4101 int descriptor = lookup.GetDescriptorIndex();
4102 representation = desc->GetDetails(descriptor).representation();
4103 }
4104 if (FLAG_track_double_fields && representation.IsDouble()) {
4105 HeapNumber* storage =
4106 HeapNumber::cast(self->RawFastPropertyAt(
4107 lookup.GetFieldIndex().field_index()));
4108 storage->set_value(value->Number());
4109 result = *value;
4110 break;
4111 }
4112 self->FastPropertyAtPut(lookup.GetFieldIndex().field_index(), *value);
4113 result = *value;
4114 break; 4127 break;
4115 }
4116 case CONSTANT: 4128 case CONSTANT:
4117 // Only replace the function if necessary. 4129 // Only replace the constant if necessary.
4118 if (*value != lookup.GetConstant()) { 4130 if (lookup.GetAttributes() != attributes ||
4119 // Preserve the attributes of this existing property. 4131 *value != lookup.GetConstant()) {
4120 attributes = lookup.GetAttributes(); 4132 result = SetPropertyToFieldWithAttributes(
4121 result = self->ConvertDescriptorToField(*name, *value, attributes); 4133 &lookup, name, value, attributes);
4122 } 4134 }
4123 break; 4135 break;
4124 case CALLBACKS: 4136 case CALLBACKS:
4137 // Callbacks are not guaranteed to be installed on the receiver. Also
4138 // perform a local lookup again. Fall through.
4125 case INTERCEPTOR: 4139 case INTERCEPTOR:
4126 // Override callback in clone 4140 self->LocalLookupRealNamedProperty(*name, &lookup);
4127 result = self->ConvertDescriptorToField(*name, *value, attributes); 4141 if (lookup.IsFound()) {
4128 break; 4142 if (lookup.IsPropertyCallbacks()) {
4129 case TRANSITION: { 4143 result = ConvertAndSetLocalProperty(
4130 Map* transition_map = lookup.GetTransitionTarget(); 4144 &lookup, *name, *value, attributes);
4131 int descriptor = transition_map->LastAdded(); 4145 } else if (lookup.IsNormal()) {
4132 4146 result = self->ReplaceSlowProperty(*name, *value, attributes);
4133 DescriptorArray* descriptors = transition_map->instance_descriptors();
4134 PropertyDetails details = descriptors->GetDetails(descriptor);
4135
4136 if (details.type() == FIELD) {
4137 if (attributes == details.attributes()) {
4138 Representation representation = details.representation();
4139 Representation value_representation =
4140 value->OptimalRepresentation(value_type);
4141 if (!value_representation.fits_into(representation)) {
4142 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
4143 descriptor, value_representation);
4144 if (!maybe_map->To(&transition_map)) return maybe_map;
4145 Object* back = transition_map->GetBackPointer();
4146 if (back->IsMap()) {
4147 MaybeObject* maybe_failure = self->MigrateToMap(Map::cast(back));
4148 if (maybe_failure->IsFailure()) return maybe_failure;
4149 }
4150 DescriptorArray* desc = transition_map->instance_descriptors();
4151 int descriptor = transition_map->LastAdded();
4152 representation = desc->GetDetails(descriptor).representation();
4153 }
4154 int field_index = descriptors->GetFieldIndex(descriptor);
4155 result = self->AddFastPropertyUsingMap(
4156 transition_map, *name, *value, field_index, representation);
4157 } else { 4147 } else {
4158 result = self->ConvertDescriptorToField(*name, *value, attributes); 4148 result = SetPropertyToFieldWithAttributes(
4149 &lookup, name, value, attributes);
4159 } 4150 }
4160 } else if (details.type() == CALLBACKS) {
4161 result = self->ConvertDescriptorToField(*name, *value, attributes);
4162 } else { 4151 } else {
4163 ASSERT(details.type() == CONSTANT); 4152 result = self->AddProperty(
4164 4153 *name, *value, attributes, kNonStrictMode, MAY_BE_STORE_FROM_KEYED,
4165 // Replace transition to CONSTANT FUNCTION with a map transition to a 4154 extensibility_check, value_type, mode);
4166 // new map with a FIELD, even if the value is a function.
4167 result = self->ConvertTransitionToMapTransition(
4168 lookup.GetTransitionIndex(), *name, *value, attributes);
4169 } 4155 }
4170 break; 4156 break;
4171 } 4157 case TRANSITION:
4158 result = SetPropertyUsingTransition(&lookup, name, value, attributes);
4159 break;
4172 case HANDLER: 4160 case HANDLER:
4173 case NONEXISTENT: 4161 case NONEXISTENT:
4174 UNREACHABLE(); 4162 UNREACHABLE();
4175 } 4163 }
4176 4164
4177 Handle<Object> hresult; 4165 Handle<Object> hresult;
4178 if (!result->ToHandle(&hresult, isolate)) return result; 4166 if (!result->ToHandle(&hresult, isolate)) return result;
4179 4167
4180 if (is_observed) { 4168 if (is_observed) {
4181 if (lookup.IsTransition()) { 4169 if (lookup.IsTransition()) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4237 // callbacks or interceptor calls. 4225 // callbacks or interceptor calls.
4238 AssertNoContextChange ncc; 4226 AssertNoContextChange ncc;
4239 4227
4240 HandleScope scope(isolate); 4228 HandleScope scope(isolate);
4241 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); 4229 Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
4242 Handle<JSObject> receiver_handle(receiver); 4230 Handle<JSObject> receiver_handle(receiver);
4243 Handle<JSObject> holder_handle(this); 4231 Handle<JSObject> holder_handle(this);
4244 Handle<String> name_handle(String::cast(name)); 4232 Handle<String> name_handle(String::cast(name));
4245 PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this); 4233 PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this);
4246 if (!interceptor->query()->IsUndefined()) { 4234 if (!interceptor->query()->IsUndefined()) {
4247 v8::NamedPropertyQuery query = 4235 v8::NamedPropertyQueryCallback query =
4248 v8::ToCData<v8::NamedPropertyQuery>(interceptor->query()); 4236 v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query());
4249 LOG(isolate, 4237 LOG(isolate,
4250 ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name)); 4238 ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name));
4251 v8::Handle<v8::Integer> result = 4239 v8::Handle<v8::Integer> result =
4252 args.Call(query, v8::Utils::ToLocal(name_handle)); 4240 args.Call(query, v8::Utils::ToLocal(name_handle));
4253 if (!result.IsEmpty()) { 4241 if (!result.IsEmpty()) {
4254 ASSERT(result->IsInt32()); 4242 ASSERT(result->IsInt32());
4255 return static_cast<PropertyAttributes>(result->Int32Value()); 4243 return static_cast<PropertyAttributes>(result->Int32Value());
4256 } 4244 }
4257 } else if (!interceptor->getter()->IsUndefined()) { 4245 } else if (!interceptor->getter()->IsUndefined()) {
4258 v8::NamedPropertyGetter getter = 4246 v8::NamedPropertyGetterCallback getter =
4259 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); 4247 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
4260 LOG(isolate, 4248 LOG(isolate,
4261 ApiNamedPropertyAccess("interceptor-named-get-has", this, name)); 4249 ApiNamedPropertyAccess("interceptor-named-get-has", this, name));
4262 v8::Handle<v8::Value> result = 4250 v8::Handle<v8::Value> result =
4263 args.Call(getter, v8::Utils::ToLocal(name_handle)); 4251 args.Call(getter, v8::Utils::ToLocal(name_handle));
4264 if (!result.IsEmpty()) return DONT_ENUM; 4252 if (!result.IsEmpty()) return DONT_ENUM;
4265 } 4253 }
4266 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle, 4254 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle,
4267 *name_handle, 4255 *name_handle,
4268 continue_search); 4256 continue_search);
4269 } 4257 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
4369 Isolate* isolate = GetIsolate(); 4357 Isolate* isolate = GetIsolate();
4370 // Make sure that the top context does not change when doing 4358 // Make sure that the top context does not change when doing
4371 // callbacks or interceptor calls. 4359 // callbacks or interceptor calls.
4372 AssertNoContextChange ncc; 4360 AssertNoContextChange ncc;
4373 HandleScope scope(isolate); 4361 HandleScope scope(isolate);
4374 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 4362 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
4375 Handle<JSReceiver> hreceiver(receiver); 4363 Handle<JSReceiver> hreceiver(receiver);
4376 Handle<JSObject> holder(this); 4364 Handle<JSObject> holder(this);
4377 PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this); 4365 PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this);
4378 if (!interceptor->query()->IsUndefined()) { 4366 if (!interceptor->query()->IsUndefined()) {
4379 v8::IndexedPropertyQuery query = 4367 v8::IndexedPropertyQueryCallback query =
4380 v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query()); 4368 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
4381 LOG(isolate, 4369 LOG(isolate,
4382 ApiIndexedPropertyAccess("interceptor-indexed-has", this, index)); 4370 ApiIndexedPropertyAccess("interceptor-indexed-has", this, index));
4383 v8::Handle<v8::Integer> result = args.Call(query, index); 4371 v8::Handle<v8::Integer> result = args.Call(query, index);
4384 if (!result.IsEmpty()) 4372 if (!result.IsEmpty())
4385 return static_cast<PropertyAttributes>(result->Int32Value()); 4373 return static_cast<PropertyAttributes>(result->Int32Value());
4386 } else if (!interceptor->getter()->IsUndefined()) { 4374 } else if (!interceptor->getter()->IsUndefined()) {
4387 v8::IndexedPropertyGetter getter = 4375 v8::IndexedPropertyGetterCallback getter =
4388 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); 4376 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
4389 LOG(isolate, 4377 LOG(isolate,
4390 ApiIndexedPropertyAccess("interceptor-indexed-get-has", this, index)); 4378 ApiIndexedPropertyAccess("interceptor-indexed-get-has", this, index));
4391 v8::Handle<v8::Value> result = args.Call(getter, index); 4379 v8::Handle<v8::Value> result = args.Call(getter, index);
4392 if (!result.IsEmpty()) return NONE; 4380 if (!result.IsEmpty()) return NONE;
4393 } 4381 }
4394 4382
4395 return holder->GetElementAttributeWithoutInterceptor( 4383 return holder->GetElementAttributeWithoutInterceptor(
4396 *hreceiver, index, continue_search); 4384 *hreceiver, index, continue_search);
4397 } 4385 }
4398 4386
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
4976 // dictionary. Put the identity hash into the new dictionary. 4964 // dictionary. Put the identity hash into the new dictionary.
4977 MaybeObject* insert_result = 4965 MaybeObject* insert_result =
4978 hashtable->Put(GetHeap()->identity_hash_string(), inline_value); 4966 hashtable->Put(GetHeap()->identity_hash_string(), inline_value);
4979 ObjectHashTable* new_table; 4967 ObjectHashTable* new_table;
4980 if (!insert_result->To(&new_table)) return insert_result; 4968 if (!insert_result->To(&new_table)) return insert_result;
4981 // We expect no resizing for the first insert. 4969 // We expect no resizing for the first insert.
4982 ASSERT_EQ(hashtable, new_table); 4970 ASSERT_EQ(hashtable, new_table);
4983 } 4971 }
4984 4972
4985 MaybeObject* store_result = 4973 MaybeObject* store_result =
4986 SetPropertyPostInterceptor(GetHeap()->hidden_string(), 4974 SetLocalPropertyIgnoreAttributes(GetHeap()->hidden_string(),
4987 hashtable, 4975 hashtable,
4988 DONT_ENUM, 4976 DONT_ENUM,
4989 kNonStrictMode, 4977 OPTIMAL_REPRESENTATION,
4990 OMIT_EXTENSIBILITY_CHECK, 4978 ALLOW_AS_CONSTANT,
4991 FORCE_FIELD); 4979 OMIT_EXTENSIBILITY_CHECK);
4992 if (store_result->IsFailure()) return store_result; 4980 if (store_result->IsFailure()) return store_result;
4993 return hashtable; 4981 return hashtable;
4994 } 4982 }
4995 4983
4996 4984
4997 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { 4985 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) {
4998 ASSERT(!IsJSGlobalProxy()); 4986 ASSERT(!IsJSGlobalProxy());
4999 // We can store the identity hash inline iff there is no backing store 4987 // We can store the identity hash inline iff there is no backing store
5000 // for hidden properties yet. 4988 // for hidden properties yet.
5001 ASSERT(HasHiddenProperties() != value->IsSmi()); 4989 ASSERT(HasHiddenProperties() != value->IsSmi());
5002 if (HasFastProperties()) { 4990 if (HasFastProperties()) {
5003 // If the object has fast properties, check whether the first slot 4991 // If the object has fast properties, check whether the first slot
5004 // in the descriptor array matches the hidden string. Since the 4992 // in the descriptor array matches the hidden string. Since the
5005 // hidden strings hash code is zero (and no other name has hash 4993 // hidden strings hash code is zero (and no other name has hash
5006 // code zero) it will always occupy the first entry if present. 4994 // code zero) it will always occupy the first entry if present.
5007 DescriptorArray* descriptors = this->map()->instance_descriptors(); 4995 DescriptorArray* descriptors = this->map()->instance_descriptors();
5008 if (descriptors->number_of_descriptors() > 0) { 4996 if (descriptors->number_of_descriptors() > 0) {
5009 int sorted_index = descriptors->GetSortedKeyIndex(0); 4997 int sorted_index = descriptors->GetSortedKeyIndex(0);
5010 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && 4998 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() &&
5011 sorted_index < map()->NumberOfOwnDescriptors()) { 4999 sorted_index < map()->NumberOfOwnDescriptors()) {
5012 ASSERT(descriptors->GetType(sorted_index) == FIELD); 5000 ASSERT(descriptors->GetType(sorted_index) == FIELD);
5013 FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), value); 5001 FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), value);
5014 return this; 5002 return this;
5015 } 5003 }
5016 } 5004 }
5017 } 5005 }
5018 MaybeObject* store_result = 5006 MaybeObject* store_result =
5019 SetPropertyPostInterceptor(GetHeap()->hidden_string(), 5007 SetLocalPropertyIgnoreAttributes(GetHeap()->hidden_string(),
5020 value, 5008 value,
5021 DONT_ENUM, 5009 DONT_ENUM,
5022 kNonStrictMode, 5010 OPTIMAL_REPRESENTATION,
5023 OMIT_EXTENSIBILITY_CHECK, 5011 ALLOW_AS_CONSTANT,
5024 FORCE_FIELD); 5012 OMIT_EXTENSIBILITY_CHECK);
5025 if (store_result->IsFailure()) return store_result; 5013 if (store_result->IsFailure()) return store_result;
5026 return this; 5014 return this;
5027 } 5015 }
5028 5016
5029 5017
5030 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, 5018 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object,
5031 Handle<Name> name, 5019 Handle<Name> name,
5032 DeleteMode mode) { 5020 DeleteMode mode) {
5033 // Check local property, ignore interceptor. 5021 // Check local property, ignore interceptor.
5034 Isolate* isolate = object->GetIsolate(); 5022 Isolate* isolate = object->GetIsolate();
(...skipping 10 matching lines...) Expand all
5045 5033
5046 Handle<Object> JSObject::DeletePropertyWithInterceptor(Handle<JSObject> object, 5034 Handle<Object> JSObject::DeletePropertyWithInterceptor(Handle<JSObject> object,
5047 Handle<Name> name) { 5035 Handle<Name> name) {
5048 Isolate* isolate = object->GetIsolate(); 5036 Isolate* isolate = object->GetIsolate();
5049 5037
5050 // TODO(rossberg): Support symbols in the API. 5038 // TODO(rossberg): Support symbols in the API.
5051 if (name->IsSymbol()) return isolate->factory()->false_value(); 5039 if (name->IsSymbol()) return isolate->factory()->false_value();
5052 5040
5053 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); 5041 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
5054 if (!interceptor->deleter()->IsUndefined()) { 5042 if (!interceptor->deleter()->IsUndefined()) {
5055 v8::NamedPropertyDeleter deleter = 5043 v8::NamedPropertyDeleterCallback deleter =
5056 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter()); 5044 v8::ToCData<v8::NamedPropertyDeleterCallback>(interceptor->deleter());
5057 LOG(isolate, 5045 LOG(isolate,
5058 ApiNamedPropertyAccess("interceptor-named-delete", *object, *name)); 5046 ApiNamedPropertyAccess("interceptor-named-delete", *object, *name));
5059 PropertyCallbackArguments args( 5047 PropertyCallbackArguments args(
5060 isolate, interceptor->data(), *object, *object); 5048 isolate, interceptor->data(), *object, *object);
5061 v8::Handle<v8::Boolean> result = 5049 v8::Handle<v8::Boolean> result =
5062 args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name))); 5050 args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name)));
5063 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 5051 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
5064 if (!result.IsEmpty()) { 5052 if (!result.IsEmpty()) {
5065 ASSERT(result->IsBoolean()); 5053 ASSERT(result->IsBoolean());
5066 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); 5054 Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
(...skipping 11 matching lines...) Expand all
5078 5066
5079 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { 5067 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) {
5080 Isolate* isolate = GetIsolate(); 5068 Isolate* isolate = GetIsolate();
5081 Heap* heap = isolate->heap(); 5069 Heap* heap = isolate->heap();
5082 // Make sure that the top context does not change when doing 5070 // Make sure that the top context does not change when doing
5083 // callbacks or interceptor calls. 5071 // callbacks or interceptor calls.
5084 AssertNoContextChange ncc; 5072 AssertNoContextChange ncc;
5085 HandleScope scope(isolate); 5073 HandleScope scope(isolate);
5086 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 5074 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
5087 if (interceptor->deleter()->IsUndefined()) return heap->false_value(); 5075 if (interceptor->deleter()->IsUndefined()) return heap->false_value();
5088 v8::IndexedPropertyDeleter deleter = 5076 v8::IndexedPropertyDeleterCallback deleter =
5089 v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter()); 5077 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
5090 Handle<JSObject> this_handle(this); 5078 Handle<JSObject> this_handle(this);
5091 LOG(isolate, 5079 LOG(isolate,
5092 ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index)); 5080 ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index));
5093 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); 5081 PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
5094 v8::Handle<v8::Boolean> result = args.Call(deleter, index); 5082 v8::Handle<v8::Boolean> result = args.Call(deleter, index);
5095 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 5083 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5096 if (!result.IsEmpty()) { 5084 if (!result.IsEmpty()) {
5097 ASSERT(result->IsBoolean()); 5085 ASSERT(result->IsBoolean());
5098 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); 5086 Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
5099 result_internal->VerifyApiCallResultType(); 5087 result_internal->VerifyApiCallResultType();
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after
5946 } 5934 }
5947 } 5935 }
5948 return false; 5936 return false;
5949 } 5937 }
5950 5938
5951 5939
5952 void JSObject::DefineElementAccessor(Handle<JSObject> object, 5940 void JSObject::DefineElementAccessor(Handle<JSObject> object,
5953 uint32_t index, 5941 uint32_t index,
5954 Handle<Object> getter, 5942 Handle<Object> getter,
5955 Handle<Object> setter, 5943 Handle<Object> setter,
5956 PropertyAttributes attributes) { 5944 PropertyAttributes attributes,
5945 v8::AccessControl access_control) {
5957 switch (object->GetElementsKind()) { 5946 switch (object->GetElementsKind()) {
5958 case FAST_SMI_ELEMENTS: 5947 case FAST_SMI_ELEMENTS:
5959 case FAST_ELEMENTS: 5948 case FAST_ELEMENTS:
5960 case FAST_DOUBLE_ELEMENTS: 5949 case FAST_DOUBLE_ELEMENTS:
5961 case FAST_HOLEY_SMI_ELEMENTS: 5950 case FAST_HOLEY_SMI_ELEMENTS:
5962 case FAST_HOLEY_ELEMENTS: 5951 case FAST_HOLEY_ELEMENTS:
5963 case FAST_HOLEY_DOUBLE_ELEMENTS: 5952 case FAST_HOLEY_DOUBLE_ELEMENTS:
5964 break; 5953 break;
5965 case EXTERNAL_PIXEL_ELEMENTS: 5954 case EXTERNAL_PIXEL_ELEMENTS:
5966 case EXTERNAL_BYTE_ELEMENTS: 5955 case EXTERNAL_BYTE_ELEMENTS:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
6004 } 5993 }
6005 } 5994 }
6006 } 5995 }
6007 break; 5996 break;
6008 } 5997 }
6009 } 5998 }
6010 5999
6011 Isolate* isolate = object->GetIsolate(); 6000 Isolate* isolate = object->GetIsolate();
6012 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair(); 6001 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair();
6013 accessors->SetComponents(*getter, *setter); 6002 accessors->SetComponents(*getter, *setter);
6003 accessors->set_access_flags(access_control);
6014 6004
6015 CALL_HEAP_FUNCTION_VOID( 6005 CALL_HEAP_FUNCTION_VOID(
6016 isolate, object->SetElementCallback(index, *accessors, attributes)); 6006 isolate, object->SetElementCallback(index, *accessors, attributes));
6017 } 6007 }
6018 6008
6019 6009
6020 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object, 6010 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object,
6021 Handle<Name> name) { 6011 Handle<Name> name) {
6022 Isolate* isolate = object->GetIsolate(); 6012 Isolate* isolate = object->GetIsolate();
6023 LookupResult result(isolate); 6013 LookupResult result(isolate);
(...skipping 11 matching lines...) Expand all
6035 } 6025 }
6036 } 6026 }
6037 return isolate->factory()->NewAccessorPair(); 6027 return isolate->factory()->NewAccessorPair();
6038 } 6028 }
6039 6029
6040 6030
6041 void JSObject::DefinePropertyAccessor(Handle<JSObject> object, 6031 void JSObject::DefinePropertyAccessor(Handle<JSObject> object,
6042 Handle<Name> name, 6032 Handle<Name> name,
6043 Handle<Object> getter, 6033 Handle<Object> getter,
6044 Handle<Object> setter, 6034 Handle<Object> setter,
6045 PropertyAttributes attributes) { 6035 PropertyAttributes attributes,
6036 v8::AccessControl access_control) {
6046 // We could assert that the property is configurable here, but we would need 6037 // We could assert that the property is configurable here, but we would need
6047 // to do a lookup, which seems to be a bit of overkill. 6038 // to do a lookup, which seems to be a bit of overkill.
6048 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); 6039 bool only_attribute_changes = getter->IsNull() && setter->IsNull();
6049 if (object->HasFastProperties() && !only_attribute_changes && 6040 if (object->HasFastProperties() && !only_attribute_changes &&
6041 access_control == v8::DEFAULT &&
6050 (object->map()->NumberOfOwnDescriptors() < 6042 (object->map()->NumberOfOwnDescriptors() <
6051 DescriptorArray::kMaxNumberOfDescriptors)) { 6043 DescriptorArray::kMaxNumberOfDescriptors)) {
6052 bool getterOk = getter->IsNull() || 6044 bool getterOk = getter->IsNull() ||
6053 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); 6045 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes);
6054 bool setterOk = !getterOk || setter->IsNull() || 6046 bool setterOk = !getterOk || setter->IsNull() ||
6055 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); 6047 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes);
6056 if (getterOk && setterOk) return; 6048 if (getterOk && setterOk) return;
6057 } 6049 }
6058 6050
6059 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); 6051 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name);
6060 accessors->SetComponents(*getter, *setter); 6052 accessors->SetComponents(*getter, *setter);
6053 accessors->set_access_flags(access_control);
6061 6054
6062 CALL_HEAP_FUNCTION_VOID( 6055 CALL_HEAP_FUNCTION_VOID(
6063 object->GetIsolate(), 6056 object->GetIsolate(),
6064 object->SetPropertyCallback(*name, *accessors, attributes)); 6057 object->SetPropertyCallback(*name, *accessors, attributes));
6065 } 6058 }
6066 6059
6067 6060
6068 bool JSObject::CanSetCallback(Name* name) { 6061 bool JSObject::CanSetCallback(Name* name) {
6069 ASSERT(!IsAccessCheckNeeded() || 6062 ASSERT(!IsAccessCheckNeeded() ||
6070 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); 6063 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET));
6071 6064
6072 // Check if there is an API defined callback object which prohibits 6065 // Check if there is an API defined callback object which prohibits
6073 // callback overwriting in this object or its prototype chain. 6066 // callback overwriting in this object or its prototype chain.
6074 // This mechanism is needed for instance in a browser setting, where 6067 // This mechanism is needed for instance in a browser setting, where
6075 // certain accessors such as window.location should not be allowed 6068 // certain accessors such as window.location should not be allowed
6076 // to be overwritten because allowing overwriting could potentially 6069 // to be overwritten because allowing overwriting could potentially
6077 // cause security problems. 6070 // cause security problems.
6078 LookupResult callback_result(GetIsolate()); 6071 LookupResult callback_result(GetIsolate());
6079 LookupCallbackProperty(name, &callback_result); 6072 LookupCallbackProperty(name, &callback_result);
6080 if (callback_result.IsFound()) { 6073 if (callback_result.IsFound()) {
6081 Object* obj = callback_result.GetCallbackObject(); 6074 Object* obj = callback_result.GetCallbackObject();
6082 if (obj->IsAccessorInfo() && 6075 if (obj->IsAccessorInfo()) {
6083 AccessorInfo::cast(obj)->prohibits_overwriting()) { 6076 return !AccessorInfo::cast(obj)->prohibits_overwriting();
6084 return false; 6077 }
6078 if (obj->IsAccessorPair()) {
6079 return !AccessorPair::cast(obj)->prohibits_overwriting();
6085 } 6080 }
6086 } 6081 }
6087
6088 return true; 6082 return true;
6089 } 6083 }
6090 6084
6091 6085
6092 MaybeObject* JSObject::SetElementCallback(uint32_t index, 6086 MaybeObject* JSObject::SetElementCallback(uint32_t index,
6093 Object* structure, 6087 Object* structure,
6094 PropertyAttributes attributes) { 6088 PropertyAttributes attributes) {
6095 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); 6089 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0);
6096 6090
6097 // Normalize elements to make this operation simple. 6091 // Normalize elements to make this operation simple.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
6155 if (maybe_ok->IsFailure()) return maybe_ok; 6149 if (maybe_ok->IsFailure()) return maybe_ok;
6156 6150
6157 return GetHeap()->undefined_value(); 6151 return GetHeap()->undefined_value();
6158 } 6152 }
6159 6153
6160 6154
6161 void JSObject::DefineAccessor(Handle<JSObject> object, 6155 void JSObject::DefineAccessor(Handle<JSObject> object,
6162 Handle<Name> name, 6156 Handle<Name> name,
6163 Handle<Object> getter, 6157 Handle<Object> getter,
6164 Handle<Object> setter, 6158 Handle<Object> setter,
6165 PropertyAttributes attributes) { 6159 PropertyAttributes attributes,
6160 v8::AccessControl access_control) {
6166 Isolate* isolate = object->GetIsolate(); 6161 Isolate* isolate = object->GetIsolate();
6167 // Check access rights if needed. 6162 // Check access rights if needed.
6168 if (object->IsAccessCheckNeeded() && 6163 if (object->IsAccessCheckNeeded() &&
6169 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { 6164 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
6170 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); 6165 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
6171 return; 6166 return;
6172 } 6167 }
6173 6168
6174 if (object->IsJSGlobalProxy()) { 6169 if (object->IsJSGlobalProxy()) {
6175 Handle<Object> proto(object->GetPrototype(), isolate); 6170 Handle<Object> proto(object->GetPrototype(), isolate);
6176 if (proto->IsNull()) return; 6171 if (proto->IsNull()) return;
6177 ASSERT(proto->IsJSGlobalObject()); 6172 ASSERT(proto->IsJSGlobalObject());
6178 DefineAccessor( 6173 DefineAccessor(Handle<JSObject>::cast(proto),
6179 Handle<JSObject>::cast(proto), name, getter, setter, attributes); 6174 name,
6175 getter,
6176 setter,
6177 attributes,
6178 access_control);
6180 return; 6179 return;
6181 } 6180 }
6182 6181
6183 // Make sure that the top context does not change when doing callbacks or 6182 // Make sure that the top context does not change when doing callbacks or
6184 // interceptor calls. 6183 // interceptor calls.
6185 AssertNoContextChange ncc; 6184 AssertNoContextChange ncc;
6186 6185
6187 // Try to flatten before operating on the string. 6186 // Try to flatten before operating on the string.
6188 if (name->IsString()) String::cast(*name)->TryFlatten(); 6187 if (name->IsString()) String::cast(*name)->TryFlatten();
6189 6188
(...skipping 15 matching lines...) Expand all
6205 LookupResult lookup(isolate); 6204 LookupResult lookup(isolate);
6206 object->LocalLookup(*name, &lookup, true); 6205 object->LocalLookup(*name, &lookup, true);
6207 preexists = lookup.IsProperty(); 6206 preexists = lookup.IsProperty();
6208 if (preexists && lookup.IsDataProperty()) { 6207 if (preexists && lookup.IsDataProperty()) {
6209 old_value = Object::GetProperty(object, name); 6208 old_value = Object::GetProperty(object, name);
6210 } 6209 }
6211 } 6210 }
6212 } 6211 }
6213 6212
6214 if (is_element) { 6213 if (is_element) {
6215 DefineElementAccessor(object, index, getter, setter, attributes); 6214 DefineElementAccessor(
6215 object, index, getter, setter, attributes, access_control);
6216 } else { 6216 } else {
6217 DefinePropertyAccessor(object, name, getter, setter, attributes); 6217 DefinePropertyAccessor(
6218 object, name, getter, setter, attributes, access_control);
6218 } 6219 }
6219 6220
6220 if (is_observed) { 6221 if (is_observed) {
6221 const char* type = preexists ? "reconfigured" : "new"; 6222 const char* type = preexists ? "reconfigured" : "new";
6222 EnqueueChangeRecord(object, type, name, old_value); 6223 EnqueueChangeRecord(object, type, name, old_value);
6223 } 6224 }
6224 } 6225 }
6225 6226
6226 6227
6227 static bool TryAccessorTransition(JSObject* self, 6228 static bool TryAccessorTransition(JSObject* self,
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
6668 if (!maybe_result->To(&result)) return maybe_result; 6669 if (!maybe_result->To(&result)) return maybe_result;
6669 6670
6670 result->InitializeDescriptors(descriptors); 6671 result->InitializeDescriptors(descriptors);
6671 6672
6672 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { 6673 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
6673 TransitionArray* transitions; 6674 TransitionArray* transitions;
6674 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); 6675 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
6675 if (!maybe_transitions->To(&transitions)) return maybe_transitions; 6676 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
6676 set_transitions(transitions); 6677 set_transitions(transitions);
6677 result->SetBackPointer(this); 6678 result->SetBackPointer(this);
6678 } else if (flag != OMIT_TRANSITION_KEEP_REPRESENTATIONS) { 6679 } else {
6679 descriptors->InitializeRepresentations(Representation::Tagged()); 6680 descriptors->InitializeRepresentations(Representation::Tagged());
6680 } 6681 }
6681 6682
6682 return result; 6683 return result;
6683 } 6684 }
6684 6685
6685 6686
6686 // Since this method is used to rewrite an existing transition tree, it can 6687 // Since this method is used to rewrite an existing transition tree, it can
6687 // always insert transitions without checking. 6688 // always insert transitions without checking.
6688 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor, 6689 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor,
(...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after
7796 // The method merges two descriptor array in three parts. Both descriptor arrays 7797 // The method merges two descriptor array in three parts. Both descriptor arrays
7797 // are identical up to |verbatim|. They also overlap in keys up to |valid|. 7798 // are identical up to |verbatim|. They also overlap in keys up to |valid|.
7798 // Between |verbatim| and |valid|, the resulting descriptor type as well as the 7799 // Between |verbatim| and |valid|, the resulting descriptor type as well as the
7799 // representation are generalized from both |this| and |other|. Beyond |valid|, 7800 // representation are generalized from both |this| and |other|. Beyond |valid|,
7800 // the descriptors are copied verbatim from |other| up to |new_size|. 7801 // the descriptors are copied verbatim from |other| up to |new_size|.
7801 // In case of incompatible types, the type and representation of |other| is 7802 // In case of incompatible types, the type and representation of |other| is
7802 // used. 7803 // used.
7803 MaybeObject* DescriptorArray::Merge(int verbatim, 7804 MaybeObject* DescriptorArray::Merge(int verbatim,
7804 int valid, 7805 int valid,
7805 int new_size, 7806 int new_size,
7807 int modify_index,
7808 StoreMode store_mode,
7806 DescriptorArray* other) { 7809 DescriptorArray* other) {
7807 ASSERT(verbatim <= valid); 7810 ASSERT(verbatim <= valid);
7808 ASSERT(valid <= new_size); 7811 ASSERT(valid <= new_size);
7809 7812
7810 DescriptorArray* result; 7813 DescriptorArray* result;
7811 // Allocate a new descriptor array large enough to hold the required 7814 // Allocate a new descriptor array large enough to hold the required
7812 // descriptors, with minimally the exact same size as this descriptor array. 7815 // descriptors, with minimally the exact same size as this descriptor array.
7813 MaybeObject* maybe_descriptors = DescriptorArray::Allocate( 7816 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(
7814 new_size, Max(new_size, other->number_of_descriptors()) - new_size); 7817 new_size, Max(new_size, other->number_of_descriptors()) - new_size);
7815 if (!maybe_descriptors->To(&result)) return maybe_descriptors; 7818 if (!maybe_descriptors->To(&result)) return maybe_descriptors;
(...skipping 13 matching lines...) Expand all
7829 result->CopyFrom(descriptor, this, descriptor, witness); 7832 result->CopyFrom(descriptor, this, descriptor, witness);
7830 } 7833 }
7831 7834
7832 // |verbatim| -> |valid| 7835 // |verbatim| -> |valid|
7833 for (; descriptor < valid; descriptor++) { 7836 for (; descriptor < valid; descriptor++) {
7834 Name* key = GetKey(descriptor); 7837 Name* key = GetKey(descriptor);
7835 PropertyDetails details = GetDetails(descriptor); 7838 PropertyDetails details = GetDetails(descriptor);
7836 PropertyDetails other_details = other->GetDetails(descriptor); 7839 PropertyDetails other_details = other->GetDetails(descriptor);
7837 7840
7838 if (details.type() == FIELD || other_details.type() == FIELD || 7841 if (details.type() == FIELD || other_details.type() == FIELD ||
7842 (store_mode == FORCE_FIELD && descriptor == modify_index) ||
7839 (details.type() == CONSTANT && 7843 (details.type() == CONSTANT &&
7840 other_details.type() == CONSTANT && 7844 other_details.type() == CONSTANT &&
7841 GetValue(descriptor) != other->GetValue(descriptor))) { 7845 GetValue(descriptor) != other->GetValue(descriptor))) {
7842 Representation representation = 7846 Representation representation =
7843 details.representation().generalize(other_details.representation()); 7847 details.representation().generalize(other_details.representation());
7844 FieldDescriptor d(key, 7848 FieldDescriptor d(key,
7845 current_offset++, 7849 current_offset++,
7846 other_details.attributes(), 7850 other_details.attributes(),
7847 representation); 7851 representation);
7848 result->Set(descriptor, &d, witness); 7852 result->Set(descriptor, &d, witness);
7849 } else { 7853 } else {
7850 result->CopyFrom(descriptor, other, descriptor, witness); 7854 result->CopyFrom(descriptor, other, descriptor, witness);
7851 } 7855 }
7852 } 7856 }
7853 7857
7854 // |valid| -> |new_size| 7858 // |valid| -> |new_size|
7855 for (; descriptor < new_size; descriptor++) { 7859 for (; descriptor < new_size; descriptor++) {
7856 PropertyDetails details = other->GetDetails(descriptor); 7860 PropertyDetails details = other->GetDetails(descriptor);
7857 if (details.type() == FIELD) { 7861 if (details.type() == FIELD ||
7862 (store_mode == FORCE_FIELD && descriptor == modify_index)) {
7858 Name* key = other->GetKey(descriptor); 7863 Name* key = other->GetKey(descriptor);
7859 FieldDescriptor d(key, 7864 FieldDescriptor d(key,
7860 current_offset++, 7865 current_offset++,
7861 details.attributes(), 7866 details.attributes(),
7862 details.representation()); 7867 details.representation());
7863 result->Set(descriptor, &d, witness); 7868 result->Set(descriptor, &d, witness);
7864 } else { 7869 } else {
7865 result->CopyFrom(descriptor, other, descriptor, witness); 7870 result->CopyFrom(descriptor, other, descriptor, witness);
7866 } 7871 }
7867 } 7872 }
(...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after
9252 ASSERT(!IsOptimized()); 9257 ASSERT(!IsOptimized());
9253 ASSERT(shared()->allows_lazy_compilation() || 9258 ASSERT(shared()->allows_lazy_compilation() ||
9254 code()->optimizable()); 9259 code()->optimizable());
9255 ASSERT(!shared()->is_generator()); 9260 ASSERT(!shared()->is_generator());
9256 set_code_no_write_barrier( 9261 set_code_no_write_barrier(
9257 GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile)); 9262 GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile));
9258 // No write barrier required, since the builtin is part of the root set. 9263 // No write barrier required, since the builtin is part of the root set.
9259 } 9264 }
9260 9265
9261 9266
9262 void JSFunction::MarkForParallelRecompilation() { 9267 void JSFunction::MarkForConcurrentRecompilation() {
9263 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); 9268 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints());
9264 ASSERT(!IsOptimized()); 9269 ASSERT(!IsOptimized());
9265 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); 9270 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable());
9266 ASSERT(!shared()->is_generator()); 9271 ASSERT(!shared()->is_generator());
9267 ASSERT(FLAG_parallel_recompilation); 9272 ASSERT(FLAG_concurrent_recompilation);
9268 if (FLAG_trace_parallel_recompilation) { 9273 if (FLAG_trace_concurrent_recompilation) {
9269 PrintF(" ** Marking "); 9274 PrintF(" ** Marking ");
9270 PrintName(); 9275 PrintName();
9271 PrintF(" for parallel recompilation.\n"); 9276 PrintF(" for concurrent recompilation.\n");
9272 } 9277 }
9273 set_code_no_write_barrier( 9278 set_code_no_write_barrier(
9274 GetIsolate()->builtins()->builtin(Builtins::kParallelRecompile)); 9279 GetIsolate()->builtins()->builtin(Builtins::kConcurrentRecompile));
9275 // No write barrier required, since the builtin is part of the root set. 9280 // No write barrier required, since the builtin is part of the root set.
9276 } 9281 }
9277 9282
9278 9283
9279 void JSFunction::MarkForInstallingRecompiledCode() { 9284 void JSFunction::MarkForInstallingRecompiledCode() {
9280 // The debugger could have switched the builtin to lazy compile. 9285 // The debugger could have switched the builtin to lazy compile.
9281 // In that case, simply carry on. It will be dealt with later. 9286 // In that case, simply carry on. It will be dealt with later.
9282 ASSERT(!IsOptimized()); 9287 ASSERT(!IsOptimized());
9283 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); 9288 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable());
9284 ASSERT(FLAG_parallel_recompilation); 9289 ASSERT(FLAG_concurrent_recompilation);
9285 set_code_no_write_barrier( 9290 set_code_no_write_barrier(
9286 GetIsolate()->builtins()->builtin(Builtins::kInstallRecompiledCode)); 9291 GetIsolate()->builtins()->builtin(Builtins::kInstallRecompiledCode));
9287 // No write barrier required, since the builtin is part of the root set. 9292 // No write barrier required, since the builtin is part of the root set.
9288 } 9293 }
9289 9294
9290 9295
9291 void JSFunction::MarkInRecompileQueue() { 9296 void JSFunction::MarkInRecompileQueue() {
9292 // We can only arrive here via the parallel-recompilation builtin. If 9297 // We can only arrive here via the concurrent-recompilation builtin. If
9293 // break points were set, the code would point to the lazy-compile builtin. 9298 // break points were set, the code would point to the lazy-compile builtin.
9294 ASSERT(!GetIsolate()->DebuggerHasBreakPoints()); 9299 ASSERT(!GetIsolate()->DebuggerHasBreakPoints());
9295 ASSERT(IsMarkedForParallelRecompilation() && !IsOptimized()); 9300 ASSERT(IsMarkedForConcurrentRecompilation() && !IsOptimized());
9296 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); 9301 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable());
9297 ASSERT(FLAG_parallel_recompilation); 9302 ASSERT(FLAG_concurrent_recompilation);
9298 if (FLAG_trace_parallel_recompilation) { 9303 if (FLAG_trace_concurrent_recompilation) {
9299 PrintF(" ** Queueing "); 9304 PrintF(" ** Queueing ");
9300 PrintName(); 9305 PrintName();
9301 PrintF(" for parallel recompilation.\n"); 9306 PrintF(" for concurrent recompilation.\n");
9302 } 9307 }
9303 set_code_no_write_barrier( 9308 set_code_no_write_barrier(
9304 GetIsolate()->builtins()->builtin(Builtins::kInRecompileQueue)); 9309 GetIsolate()->builtins()->builtin(Builtins::kInRecompileQueue));
9305 // No write barrier required, since the builtin is part of the root set. 9310 // No write barrier required, since the builtin is part of the root set.
9306 } 9311 }
9307 9312
9308 9313
9309 static bool CompileLazyHelper(CompilationInfo* info, 9314 static bool CompileLazyHelper(CompilationInfo* info,
9310 ClearExceptionFlag flag) { 9315 ClearExceptionFlag flag) {
9311 // Compile the source information to a code object. 9316 // Compile the source information to a code object.
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
9670 SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); 9675 SmartArrayPointer<char> name = shared()->DebugName()->ToCString();
9671 PrintF(out, "%s", *name); 9676 PrintF(out, "%s", *name);
9672 } 9677 }
9673 9678
9674 9679
9675 Context* JSFunction::NativeContextFromLiterals(FixedArray* literals) { 9680 Context* JSFunction::NativeContextFromLiterals(FixedArray* literals) {
9676 return Context::cast(literals->get(JSFunction::kLiteralNativeContextIndex)); 9681 return Context::cast(literals->get(JSFunction::kLiteralNativeContextIndex));
9677 } 9682 }
9678 9683
9679 9684
9680 bool JSFunction::PassesHydrogenFilter() { 9685 // The filter is a pattern that matches function names in this way:
9686 // "*" all; the default
9687 // "-" all but the top-level function
9688 // "-name" all but the function "name"
9689 // "" only the top-level function
9690 // "name" only the function "name"
9691 // "name*" only functions starting with "name"
9692 bool JSFunction::PassesFilter(const char* raw_filter) {
9693 if (*raw_filter == '*') return true;
9681 String* name = shared()->DebugName(); 9694 String* name = shared()->DebugName();
9682 // The filter string is a pattern that matches functions in this way: 9695 Vector<const char> filter = CStrVector(raw_filter);
9683 // "*" all; the default 9696 if (filter.length() == 0) return name->length() == 0;
9684 // "-" all but the top-level function 9697 if (filter[0] != '-' && name->IsUtf8EqualTo(filter)) return true;
9685 // "-name" all but the function "name" 9698 if (filter[0] == '-' &&
9686 // "" only the top-level function 9699 !name->IsUtf8EqualTo(filter.SubVector(1, filter.length()))) {
9687 // "name" only the function "name" 9700 return true;
9688 // "name*" only functions starting with "name"
9689 if (*FLAG_hydrogen_filter != '*') {
9690 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter);
9691 if (filter.length() == 0) return name->length() == 0;
9692 if (filter[0] != '-' && name->IsUtf8EqualTo(filter)) return true;
9693 if (filter[0] == '-' &&
9694 !name->IsUtf8EqualTo(filter.SubVector(1, filter.length()))) {
9695 return true;
9696 }
9697 if (filter[filter.length() - 1] == '*' &&
9698 name->IsUtf8EqualTo(filter.SubVector(0, filter.length() - 1), true)) {
9699 return true;
9700 }
9701 return false;
9702 } 9701 }
9703 9702 if (filter[filter.length() - 1] == '*' &&
9704 return true; 9703 name->IsUtf8EqualTo(filter.SubVector(0, filter.length() - 1), true)) {
9704 return true;
9705 }
9706 return false;
9705 } 9707 }
9706 9708
9707 9709
9708 MaybeObject* Oddball::Initialize(const char* to_string, 9710 MaybeObject* Oddball::Initialize(const char* to_string,
9709 Object* to_number, 9711 Object* to_number,
9710 byte kind) { 9712 byte kind) {
9711 String* internalized_to_string; 9713 String* internalized_to_string;
9712 { MaybeObject* maybe_string = 9714 { MaybeObject* maybe_string =
9713 Isolate::Current()->heap()->InternalizeUtf8String( 9715 Isolate::Current()->heap()->InternalizeUtf8String(
9714 CStrVector(to_string)); 9716 CStrVector(to_string));
(...skipping 1855 matching lines...) Expand 10 before | Expand all | Expand 10 after
11570 SetPropertyMode set_mode) { 11572 SetPropertyMode set_mode) {
11571 Isolate* isolate = GetIsolate(); 11573 Isolate* isolate = GetIsolate();
11572 // Make sure that the top context does not change when doing 11574 // Make sure that the top context does not change when doing
11573 // callbacks or interceptor calls. 11575 // callbacks or interceptor calls.
11574 AssertNoContextChange ncc; 11576 AssertNoContextChange ncc;
11575 HandleScope scope(isolate); 11577 HandleScope scope(isolate);
11576 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 11578 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
11577 Handle<JSObject> this_handle(this); 11579 Handle<JSObject> this_handle(this);
11578 Handle<Object> value_handle(value, isolate); 11580 Handle<Object> value_handle(value, isolate);
11579 if (!interceptor->setter()->IsUndefined()) { 11581 if (!interceptor->setter()->IsUndefined()) {
11580 v8::IndexedPropertySetter setter = 11582 v8::IndexedPropertySetterCallback setter =
11581 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); 11583 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
11582 LOG(isolate, 11584 LOG(isolate,
11583 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); 11585 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index));
11584 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); 11586 PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
11585 v8::Handle<v8::Value> result = 11587 v8::Handle<v8::Value> result =
11586 args.Call(setter, index, v8::Utils::ToLocal(value_handle)); 11588 args.Call(setter, index, v8::Utils::ToLocal(value_handle));
11587 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 11589 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
11588 if (!result.IsEmpty()) return *value_handle; 11590 if (!result.IsEmpty()) return *value_handle;
11589 } 11591 }
11590 MaybeObject* raw_result = 11592 MaybeObject* raw_result =
11591 this_handle->SetElementWithoutInterceptor(index, 11593 this_handle->SetElementWithoutInterceptor(index,
(...skipping 12 matching lines...) Expand all
11604 uint32_t index, 11606 uint32_t index,
11605 Object* holder) { 11607 Object* holder) {
11606 Isolate* isolate = GetIsolate(); 11608 Isolate* isolate = GetIsolate();
11607 ASSERT(!structure->IsForeign()); 11609 ASSERT(!structure->IsForeign());
11608 11610
11609 // api style callbacks. 11611 // api style callbacks.
11610 if (structure->IsExecutableAccessorInfo()) { 11612 if (structure->IsExecutableAccessorInfo()) {
11611 Handle<ExecutableAccessorInfo> data( 11613 Handle<ExecutableAccessorInfo> data(
11612 ExecutableAccessorInfo::cast(structure)); 11614 ExecutableAccessorInfo::cast(structure));
11613 Object* fun_obj = data->getter(); 11615 Object* fun_obj = data->getter();
11614 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); 11616 v8::AccessorGetterCallback call_fun =
11617 v8::ToCData<v8::AccessorGetterCallback>(fun_obj);
11615 if (call_fun == NULL) return isolate->heap()->undefined_value(); 11618 if (call_fun == NULL) return isolate->heap()->undefined_value();
11616 HandleScope scope(isolate); 11619 HandleScope scope(isolate);
11617 Handle<JSObject> self(JSObject::cast(receiver)); 11620 Handle<JSObject> self(JSObject::cast(receiver));
11618 Handle<JSObject> holder_handle(JSObject::cast(holder)); 11621 Handle<JSObject> holder_handle(JSObject::cast(holder));
11619 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 11622 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
11620 Handle<String> key = isolate->factory()->NumberToString(number); 11623 Handle<String> key = isolate->factory()->NumberToString(number);
11621 LOG(isolate, ApiNamedPropertyAccess("load", *self, *key)); 11624 LOG(isolate, ApiNamedPropertyAccess("load", *self, *key));
11622 PropertyCallbackArguments 11625 PropertyCallbackArguments
11623 args(isolate, data->data(), *self, *holder_handle); 11626 args(isolate, data->data(), *self, *holder_handle);
11624 v8::Handle<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(key)); 11627 v8::Handle<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(key));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
11669 // callbacks should be phased out. 11672 // callbacks should be phased out.
11670 ASSERT(!structure->IsForeign()); 11673 ASSERT(!structure->IsForeign());
11671 11674
11672 if (structure->IsExecutableAccessorInfo()) { 11675 if (structure->IsExecutableAccessorInfo()) {
11673 // api style callbacks 11676 // api style callbacks
11674 Handle<JSObject> self(this); 11677 Handle<JSObject> self(this);
11675 Handle<JSObject> holder_handle(JSObject::cast(holder)); 11678 Handle<JSObject> holder_handle(JSObject::cast(holder));
11676 Handle<ExecutableAccessorInfo> data( 11679 Handle<ExecutableAccessorInfo> data(
11677 ExecutableAccessorInfo::cast(structure)); 11680 ExecutableAccessorInfo::cast(structure));
11678 Object* call_obj = data->setter(); 11681 Object* call_obj = data->setter();
11679 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); 11682 v8::AccessorSetterCallback call_fun =
11683 v8::ToCData<v8::AccessorSetterCallback>(call_obj);
11680 if (call_fun == NULL) return value; 11684 if (call_fun == NULL) return value;
11681 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 11685 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
11682 Handle<String> key(isolate->factory()->NumberToString(number)); 11686 Handle<String> key(isolate->factory()->NumberToString(number));
11683 LOG(isolate, ApiNamedPropertyAccess("store", *self, *key)); 11687 LOG(isolate, ApiNamedPropertyAccess("store", *self, *key));
11684 PropertyCallbackArguments 11688 PropertyCallbackArguments
11685 args(isolate, data->data(), *self, *holder_handle); 11689 args(isolate, data->data(), *self, *holder_handle);
11686 args.Call(call_fun, 11690 args.Call(call_fun,
11687 v8::Utils::ToLocal(key), 11691 v8::Utils::ToLocal(key),
11688 v8::Utils::ToLocal(value_handle)); 11692 v8::Utils::ToLocal(value_handle));
11689 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 11693 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
(...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after
12578 uint32_t index) { 12582 uint32_t index) {
12579 Isolate* isolate = GetIsolate(); 12583 Isolate* isolate = GetIsolate();
12580 // Make sure that the top context does not change when doing 12584 // Make sure that the top context does not change when doing
12581 // callbacks or interceptor calls. 12585 // callbacks or interceptor calls.
12582 AssertNoContextChange ncc; 12586 AssertNoContextChange ncc;
12583 HandleScope scope(isolate); 12587 HandleScope scope(isolate);
12584 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor(), isolate); 12588 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor(), isolate);
12585 Handle<Object> this_handle(receiver, isolate); 12589 Handle<Object> this_handle(receiver, isolate);
12586 Handle<JSObject> holder_handle(this, isolate); 12590 Handle<JSObject> holder_handle(this, isolate);
12587 if (!interceptor->getter()->IsUndefined()) { 12591 if (!interceptor->getter()->IsUndefined()) {
12588 v8::IndexedPropertyGetter getter = 12592 v8::IndexedPropertyGetterCallback getter =
12589 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); 12593 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
12590 LOG(isolate, 12594 LOG(isolate,
12591 ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); 12595 ApiIndexedPropertyAccess("interceptor-indexed-get", this, index));
12592 PropertyCallbackArguments 12596 PropertyCallbackArguments
12593 args(isolate, interceptor->data(), receiver, this); 12597 args(isolate, interceptor->data(), receiver, this);
12594 v8::Handle<v8::Value> result = args.Call(getter, index); 12598 v8::Handle<v8::Value> result = args.Call(getter, index);
12595 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 12599 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
12596 if (!result.IsEmpty()) { 12600 if (!result.IsEmpty()) {
12597 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); 12601 Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
12598 result_internal->VerifyApiCallResultType(); 12602 result_internal->VerifyApiCallResultType();
12599 return *result_internal; 12603 return *result_internal;
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
12883 if (name->IsSymbol()) return GetHeap()->undefined_value(); 12887 if (name->IsSymbol()) return GetHeap()->undefined_value();
12884 12888
12885 Isolate* isolate = GetIsolate(); 12889 Isolate* isolate = GetIsolate();
12886 InterceptorInfo* interceptor = GetNamedInterceptor(); 12890 InterceptorInfo* interceptor = GetNamedInterceptor();
12887 HandleScope scope(isolate); 12891 HandleScope scope(isolate);
12888 Handle<Object> receiver_handle(receiver, isolate); 12892 Handle<Object> receiver_handle(receiver, isolate);
12889 Handle<JSObject> holder_handle(this); 12893 Handle<JSObject> holder_handle(this);
12890 Handle<String> name_handle(String::cast(name)); 12894 Handle<String> name_handle(String::cast(name));
12891 12895
12892 if (!interceptor->getter()->IsUndefined()) { 12896 if (!interceptor->getter()->IsUndefined()) {
12893 v8::NamedPropertyGetter getter = 12897 v8::NamedPropertyGetterCallback getter =
12894 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); 12898 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
12895 LOG(isolate, 12899 LOG(isolate,
12896 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); 12900 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name));
12897 PropertyCallbackArguments 12901 PropertyCallbackArguments
12898 args(isolate, interceptor->data(), receiver, this); 12902 args(isolate, interceptor->data(), receiver, this);
12899 v8::Handle<v8::Value> result = 12903 v8::Handle<v8::Value> result =
12900 args.Call(getter, v8::Utils::ToLocal(name_handle)); 12904 args.Call(getter, v8::Utils::ToLocal(name_handle));
12901 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 12905 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
12902 if (!result.IsEmpty()) { 12906 if (!result.IsEmpty()) {
12903 *attributes = NONE; 12907 *attributes = NONE;
12904 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); 12908 Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
(...skipping 2451 matching lines...) Expand 10 before | Expand all | Expand 10 after
15356 } 15360 }
15357 15361
15358 15362
15359 MaybeObject* ObjectHashSet::Add(Object* key) { 15363 MaybeObject* ObjectHashSet::Add(Object* key) {
15360 ASSERT(IsKey(key)); 15364 ASSERT(IsKey(key));
15361 15365
15362 // Make sure the key object has an identity hash code. 15366 // Make sure the key object has an identity hash code.
15363 int hash; 15367 int hash;
15364 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); 15368 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
15365 if (maybe_hash->IsFailure()) return maybe_hash; 15369 if (maybe_hash->IsFailure()) return maybe_hash;
15370 ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash);
15366 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); 15371 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
15367 } 15372 }
15368 int entry = FindEntry(key); 15373 int entry = FindEntry(key);
15369 15374
15370 // Check whether key is already present. 15375 // Check whether key is already present.
15371 if (entry != kNotFound) return this; 15376 if (entry != kNotFound) return this;
15372 15377
15373 // Check whether the hash set should be extended and add entry. 15378 // Check whether the hash set should be extended and add entry.
15374 Object* obj; 15379 Object* obj;
15375 { MaybeObject* maybe_obj = EnsureCapacity(1, key); 15380 { MaybeObject* maybe_obj = EnsureCapacity(1, key);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
15417 } 15422 }
15418 15423
15419 15424
15420 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) { 15425 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) {
15421 ASSERT(IsKey(key)); 15426 ASSERT(IsKey(key));
15422 15427
15423 // Make sure the key object has an identity hash code. 15428 // Make sure the key object has an identity hash code.
15424 int hash; 15429 int hash;
15425 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); 15430 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
15426 if (maybe_hash->IsFailure()) return maybe_hash; 15431 if (maybe_hash->IsFailure()) return maybe_hash;
15432 ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash);
15427 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); 15433 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
15428 } 15434 }
15429 int entry = FindEntry(key); 15435 int entry = FindEntry(key);
15430 15436
15431 // Check whether to perform removal operation. 15437 // Check whether to perform removal operation.
15432 if (value->IsTheHole()) { 15438 if (value->IsTheHole()) {
15433 if (entry == kNotFound) return this; 15439 if (entry == kNotFound) return this;
15434 RemoveEntry(entry); 15440 RemoveEntry(entry);
15435 return Shrink(key); 15441 return Shrink(key);
15436 } 15442 }
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
16007 #define ERROR_MESSAGES_TEXTS(C, T) T, 16013 #define ERROR_MESSAGES_TEXTS(C, T) T,
16008 static const char* error_messages_[] = { 16014 static const char* error_messages_[] = {
16009 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16015 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16010 }; 16016 };
16011 #undef ERROR_MESSAGES_TEXTS 16017 #undef ERROR_MESSAGES_TEXTS
16012 return error_messages_[reason]; 16018 return error_messages_[reason];
16013 } 16019 }
16014 16020
16015 16021
16016 } } // namespace v8::internal 16022 } } // 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