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

Side by Side Diff: src/objects.cc

Issue 148503002: A64: Synchronize with r15545. (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 21 matching lines...) Expand all
32 #include "arguments.h" 32 #include "arguments.h"
33 #include "bootstrapper.h" 33 #include "bootstrapper.h"
34 #include "codegen.h" 34 #include "codegen.h"
35 #include "debug.h" 35 #include "debug.h"
36 #include "deoptimizer.h" 36 #include "deoptimizer.h"
37 #include "date.h" 37 #include "date.h"
38 #include "elements.h" 38 #include "elements.h"
39 #include "execution.h" 39 #include "execution.h"
40 #include "full-codegen.h" 40 #include "full-codegen.h"
41 #include "hydrogen.h" 41 #include "hydrogen.h"
42 #include "isolate-inl.h"
42 #include "objects-inl.h" 43 #include "objects-inl.h"
43 #include "objects-visiting.h" 44 #include "objects-visiting.h"
44 #include "objects-visiting-inl.h" 45 #include "objects-visiting-inl.h"
45 #include "macro-assembler.h" 46 #include "macro-assembler.h"
46 #include "mark-compact.h" 47 #include "mark-compact.h"
47 #include "safepoint-table.h" 48 #include "safepoint-table.h"
48 #include "string-stream.h" 49 #include "string-stream.h"
49 #include "utils.h" 50 #include "utils.h"
50 51
51 #ifdef ENABLE_DISASSEMBLER 52 #ifdef ENABLE_DISASSEMBLER
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 ASSERT(!HasFastProperties()); 623 ASSERT(!HasFastProperties());
623 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 624 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
624 if (IsGlobalObject()) { 625 if (IsGlobalObject()) {
625 value = PropertyCell::cast(value)->value(); 626 value = PropertyCell::cast(value)->value();
626 } 627 }
627 ASSERT(!value->IsPropertyCell() && !value->IsCell()); 628 ASSERT(!value->IsPropertyCell() && !value->IsCell());
628 return value; 629 return value;
629 } 630 }
630 631
631 632
632 Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) { 633 Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object,
634 LookupResult* result,
635 Handle<Object> value) {
636 CALL_HEAP_FUNCTION(object->GetIsolate(),
637 object->SetNormalizedProperty(result, *value),
638 Object);
639 }
640
641
642 MaybeObject* JSObject::SetNormalizedProperty(LookupResult* result,
643 Object* value) {
633 ASSERT(!HasFastProperties()); 644 ASSERT(!HasFastProperties());
634 if (IsGlobalObject()) { 645 if (IsGlobalObject()) {
635 PropertyCell* cell = PropertyCell::cast( 646 PropertyCell* cell = PropertyCell::cast(
636 property_dictionary()->ValueAt(result->GetDictionaryEntry())); 647 property_dictionary()->ValueAt(result->GetDictionaryEntry()));
637 cell->set_value(value); 648 MaybeObject* maybe_type = cell->SetValueInferType(value);
649 if (maybe_type->IsFailure()) return maybe_type;
638 } else { 650 } else {
639 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); 651 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value);
640 } 652 }
641 return value; 653 return value;
642 } 654 }
643 655
644 656
645 Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object, 657 Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object,
646 Handle<Name> key, 658 Handle<Name> key,
647 Handle<Object> value, 659 Handle<Object> value,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 enumeration_index = original_details.dictionary_index(); 695 enumeration_index = original_details.dictionary_index();
684 ASSERT(enumeration_index > 0); 696 ASSERT(enumeration_index > 0);
685 } 697 }
686 698
687 details = PropertyDetails( 699 details = PropertyDetails(
688 details.attributes(), details.type(), enumeration_index); 700 details.attributes(), details.type(), enumeration_index);
689 701
690 if (IsGlobalObject()) { 702 if (IsGlobalObject()) {
691 PropertyCell* cell = 703 PropertyCell* cell =
692 PropertyCell::cast(property_dictionary()->ValueAt(entry)); 704 PropertyCell::cast(property_dictionary()->ValueAt(entry));
693 cell->set_value(value); 705 MaybeObject* maybe_type = cell->SetValueInferType(value);
706 if (maybe_type->IsFailure()) return maybe_type;
694 // Please note we have to update the property details. 707 // Please note we have to update the property details.
695 property_dictionary()->DetailsAtPut(entry, details); 708 property_dictionary()->DetailsAtPut(entry, details);
696 } else { 709 } else {
697 property_dictionary()->SetEntry(entry, name, value, details); 710 property_dictionary()->SetEntry(entry, name, value, details);
698 } 711 }
699 return value; 712 return value;
700 } 713 }
701 714
702 715
703 MaybeObject* JSObject::DeleteNormalizedProperty(Name* name, DeleteMode mode) { 716 MaybeObject* JSObject::DeleteNormalizedProperty(Name* name, DeleteMode mode) {
(...skipping 11 matching lines...) Expand all
715 // from the DontDelete cell without checking if it contains 728 // from the DontDelete cell without checking if it contains
716 // the hole value. 729 // the hole value.
717 Map* new_map; 730 Map* new_map;
718 MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); 731 MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
719 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 732 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
720 733
721 ASSERT(new_map->is_dictionary_map()); 734 ASSERT(new_map->is_dictionary_map());
722 set_map(new_map); 735 set_map(new_map);
723 } 736 }
724 PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry)); 737 PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
725 cell->set_value(cell->GetHeap()->the_hole_value()); 738 MaybeObject* maybe_type =
739 cell->SetValueInferType(cell->GetHeap()->the_hole_value());
740 if (maybe_type->IsFailure()) return maybe_type;
726 dictionary->DetailsAtPut(entry, details.AsDeleted()); 741 dictionary->DetailsAtPut(entry, details.AsDeleted());
727 } else { 742 } else {
728 Object* deleted = dictionary->DeleteProperty(entry, mode); 743 Object* deleted = dictionary->DeleteProperty(entry, mode);
729 if (deleted == GetHeap()->true_value()) { 744 if (deleted == GetHeap()->true_value()) {
730 FixedArray* new_properties = NULL; 745 FixedArray* new_properties = NULL;
731 MaybeObject* maybe_properties = dictionary->Shrink(name); 746 MaybeObject* maybe_properties = dictionary->Shrink(name);
732 if (!maybe_properties->To(&new_properties)) { 747 if (!maybe_properties->To(&new_properties)) {
733 return maybe_properties; 748 return maybe_properties;
734 } 749 }
735 set_properties(new_properties); 750 set_properties(new_properties);
(...skipping 1186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1922 Object* value, 1937 Object* value,
1923 PropertyAttributes attributes) { 1938 PropertyAttributes attributes) {
1924 ASSERT(!HasFastProperties()); 1939 ASSERT(!HasFastProperties());
1925 NameDictionary* dict = property_dictionary(); 1940 NameDictionary* dict = property_dictionary();
1926 Object* store_value = value; 1941 Object* store_value = value;
1927 if (IsGlobalObject()) { 1942 if (IsGlobalObject()) {
1928 // In case name is an orphaned property reuse the cell. 1943 // In case name is an orphaned property reuse the cell.
1929 int entry = dict->FindEntry(name); 1944 int entry = dict->FindEntry(name);
1930 if (entry != NameDictionary::kNotFound) { 1945 if (entry != NameDictionary::kNotFound) {
1931 store_value = dict->ValueAt(entry); 1946 store_value = dict->ValueAt(entry);
1932 PropertyCell::cast(store_value)->set_value(value); 1947 MaybeObject* maybe_type =
1948 PropertyCell::cast(store_value)->SetValueInferType(value);
1949 if (maybe_type->IsFailure()) return maybe_type;
1933 // Assign an enumeration index to the property and update 1950 // Assign an enumeration index to the property and update
1934 // SetNextEnumerationIndex. 1951 // SetNextEnumerationIndex.
1935 int index = dict->NextEnumerationIndex(); 1952 int index = dict->NextEnumerationIndex();
1936 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); 1953 PropertyDetails details = PropertyDetails(attributes, NORMAL, index);
1937 dict->SetNextEnumerationIndex(index + 1); 1954 dict->SetNextEnumerationIndex(index + 1);
1938 dict->SetEntry(entry, name, store_value, details); 1955 dict->SetEntry(entry, name, store_value, details);
1939 return value; 1956 return value;
1940 } 1957 }
1941 Heap* heap = GetHeap(); 1958 Heap* heap = GetHeap();
1942 { MaybeObject* maybe_store_value = 1959 { MaybeObject* maybe_store_value =
1943 heap->AllocatePropertyCell(value); 1960 heap->AllocatePropertyCell(value);
1944 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; 1961 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
1945 } 1962 }
1946 PropertyCell::cast(store_value)->set_value(value); 1963 MaybeObject* maybe_type =
1964 PropertyCell::cast(store_value)->SetValueInferType(value);
1965 if (maybe_type->IsFailure()) return maybe_type;
1947 } 1966 }
1948 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); 1967 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
1949 Object* result; 1968 Object* result;
1950 { MaybeObject* maybe_result = dict->Add(name, store_value, details); 1969 { MaybeObject* maybe_result = dict->Add(name, store_value, details);
1951 if (!maybe_result->ToObject(&result)) return maybe_result; 1970 if (!maybe_result->ToObject(&result)) return maybe_result;
1952 } 1971 }
1953 if (dict != result) set_properties(NameDictionary::cast(result)); 1972 if (dict != result) set_properties(NameDictionary::cast(result));
1954 return value; 1973 return value;
1955 } 1974 }
1956 1975
(...skipping 3874 matching lines...) Expand 10 before | Expand all | Expand 10 after
5831 PropertyDetails(attributes, CALLBACKS, index)); 5850 PropertyDetails(attributes, CALLBACKS, index));
5832 } 5851 }
5833 AccessorPair::cast(result)->SetComponents(getter, setter); 5852 AccessorPair::cast(result)->SetComponents(getter, setter);
5834 return true; 5853 return true;
5835 } 5854 }
5836 } 5855 }
5837 return false; 5856 return false;
5838 } 5857 }
5839 5858
5840 5859
5841 MaybeObject* JSObject::DefineElementAccessor(uint32_t index, 5860 void JSObject::DefineElementAccessor(Handle<JSObject> object,
5842 Object* getter, 5861 uint32_t index,
5843 Object* setter, 5862 Handle<Object> getter,
5844 PropertyAttributes attributes) { 5863 Handle<Object> setter,
5845 switch (GetElementsKind()) { 5864 PropertyAttributes attributes) {
5865 switch (object->GetElementsKind()) {
5846 case FAST_SMI_ELEMENTS: 5866 case FAST_SMI_ELEMENTS:
5847 case FAST_ELEMENTS: 5867 case FAST_ELEMENTS:
5848 case FAST_DOUBLE_ELEMENTS: 5868 case FAST_DOUBLE_ELEMENTS:
5849 case FAST_HOLEY_SMI_ELEMENTS: 5869 case FAST_HOLEY_SMI_ELEMENTS:
5850 case FAST_HOLEY_ELEMENTS: 5870 case FAST_HOLEY_ELEMENTS:
5851 case FAST_HOLEY_DOUBLE_ELEMENTS: 5871 case FAST_HOLEY_DOUBLE_ELEMENTS:
5852 break; 5872 break;
5853 case EXTERNAL_PIXEL_ELEMENTS: 5873 case EXTERNAL_PIXEL_ELEMENTS:
5854 case EXTERNAL_BYTE_ELEMENTS: 5874 case EXTERNAL_BYTE_ELEMENTS:
5855 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 5875 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
5856 case EXTERNAL_SHORT_ELEMENTS: 5876 case EXTERNAL_SHORT_ELEMENTS:
5857 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 5877 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
5858 case EXTERNAL_INT_ELEMENTS: 5878 case EXTERNAL_INT_ELEMENTS:
5859 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 5879 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
5860 case EXTERNAL_FLOAT_ELEMENTS: 5880 case EXTERNAL_FLOAT_ELEMENTS:
5861 case EXTERNAL_DOUBLE_ELEMENTS: 5881 case EXTERNAL_DOUBLE_ELEMENTS:
5862 // Ignore getters and setters on pixel and external array elements. 5882 // Ignore getters and setters on pixel and external array elements.
5863 return GetHeap()->undefined_value(); 5883 return;
5864 case DICTIONARY_ELEMENTS: 5884 case DICTIONARY_ELEMENTS:
5865 if (UpdateGetterSetterInDictionary(element_dictionary(), 5885 if (UpdateGetterSetterInDictionary(object->element_dictionary(),
5866 index, 5886 index,
5867 getter, 5887 *getter,
5868 setter, 5888 *setter,
5869 attributes)) { 5889 attributes)) {
5870 return GetHeap()->undefined_value(); 5890 return;
5871 } 5891 }
5872 break; 5892 break;
5873 case NON_STRICT_ARGUMENTS_ELEMENTS: { 5893 case NON_STRICT_ARGUMENTS_ELEMENTS: {
5874 // Ascertain whether we have read-only properties or an existing 5894 // Ascertain whether we have read-only properties or an existing
5875 // getter/setter pair in an arguments elements dictionary backing 5895 // getter/setter pair in an arguments elements dictionary backing
5876 // store. 5896 // store.
5877 FixedArray* parameter_map = FixedArray::cast(elements()); 5897 FixedArray* parameter_map = FixedArray::cast(object->elements());
5878 uint32_t length = parameter_map->length(); 5898 uint32_t length = parameter_map->length();
5879 Object* probe = 5899 Object* probe =
5880 index < (length - 2) ? parameter_map->get(index + 2) : NULL; 5900 index < (length - 2) ? parameter_map->get(index + 2) : NULL;
5881 if (probe == NULL || probe->IsTheHole()) { 5901 if (probe == NULL || probe->IsTheHole()) {
5882 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 5902 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
5883 if (arguments->IsDictionary()) { 5903 if (arguments->IsDictionary()) {
5884 SeededNumberDictionary* dictionary = 5904 SeededNumberDictionary* dictionary =
5885 SeededNumberDictionary::cast(arguments); 5905 SeededNumberDictionary::cast(arguments);
5886 if (UpdateGetterSetterInDictionary(dictionary, 5906 if (UpdateGetterSetterInDictionary(dictionary,
5887 index, 5907 index,
5888 getter, 5908 *getter,
5889 setter, 5909 *setter,
5890 attributes)) { 5910 attributes)) {
5891 return GetHeap()->undefined_value(); 5911 return;
5892 } 5912 }
5893 } 5913 }
5894 } 5914 }
5895 break; 5915 break;
5896 } 5916 }
5897 } 5917 }
5898 5918
5899 AccessorPair* accessors; 5919 Isolate* isolate = object->GetIsolate();
5900 { MaybeObject* maybe_accessors = GetHeap()->AllocateAccessorPair(); 5920 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair();
5901 if (!maybe_accessors->To(&accessors)) return maybe_accessors; 5921 accessors->SetComponents(*getter, *setter);
5902 }
5903 accessors->SetComponents(getter, setter);
5904 5922
5905 return SetElementCallback(index, accessors, attributes); 5923 CALL_HEAP_FUNCTION_VOID(
5924 isolate, object->SetElementCallback(index, *accessors, attributes));
5906 } 5925 }
5907 5926
5908 5927
5909 MaybeObject* JSObject::CreateAccessorPairFor(Name* name) { 5928 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object,
5910 LookupResult result(GetHeap()->isolate()); 5929 Handle<Name> name) {
5911 LocalLookupRealNamedProperty(name, &result); 5930 Isolate* isolate = object->GetIsolate();
5931 LookupResult result(isolate);
5932 object->LocalLookupRealNamedProperty(*name, &result);
5912 if (result.IsPropertyCallbacks()) { 5933 if (result.IsPropertyCallbacks()) {
5913 // Note that the result can actually have IsDontDelete() == true when we 5934 // Note that the result can actually have IsDontDelete() == true when we
5914 // e.g. have to fall back to the slow case while adding a setter after 5935 // e.g. have to fall back to the slow case while adding a setter after
5915 // successfully reusing a map transition for a getter. Nevertheless, this is 5936 // successfully reusing a map transition for a getter. Nevertheless, this is
5916 // OK, because the assertion only holds for the whole addition of both 5937 // OK, because the assertion only holds for the whole addition of both
5917 // accessors, not for the addition of each part. See first comment in 5938 // accessors, not for the addition of each part. See first comment in
5918 // DefinePropertyAccessor below. 5939 // DefinePropertyAccessor below.
5919 Object* obj = result.GetCallbackObject(); 5940 Object* obj = result.GetCallbackObject();
5920 if (obj->IsAccessorPair()) { 5941 if (obj->IsAccessorPair()) {
5921 return AccessorPair::cast(obj)->Copy(); 5942 return AccessorPair::Copy(handle(AccessorPair::cast(obj), isolate));
5922 } 5943 }
5923 } 5944 }
5924 return GetHeap()->AllocateAccessorPair(); 5945 return isolate->factory()->NewAccessorPair();
5925 } 5946 }
5926 5947
5927 5948
5928 MaybeObject* JSObject::DefinePropertyAccessor(Name* name, 5949 void JSObject::DefinePropertyAccessor(Handle<JSObject> object,
5929 Object* getter, 5950 Handle<Name> name,
5930 Object* setter, 5951 Handle<Object> getter,
5931 PropertyAttributes attributes) { 5952 Handle<Object> setter,
5953 PropertyAttributes attributes) {
5932 // We could assert that the property is configurable here, but we would need 5954 // We could assert that the property is configurable here, but we would need
5933 // to do a lookup, which seems to be a bit of overkill. 5955 // to do a lookup, which seems to be a bit of overkill.
5934 Heap* heap = GetHeap();
5935 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); 5956 bool only_attribute_changes = getter->IsNull() && setter->IsNull();
5936 if (HasFastProperties() && !only_attribute_changes && 5957 if (object->HasFastProperties() && !only_attribute_changes &&
5937 (map()->NumberOfOwnDescriptors() < 5958 (object->map()->NumberOfOwnDescriptors() <
5938 DescriptorArray::kMaxNumberOfDescriptors)) { 5959 DescriptorArray::kMaxNumberOfDescriptors)) {
5939 MaybeObject* getterOk = heap->undefined_value(); 5960 bool getterOk = getter->IsNull() ||
5940 if (!getter->IsNull()) { 5961 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes);
5941 getterOk = DefineFastAccessor(name, ACCESSOR_GETTER, getter, attributes); 5962 bool setterOk = !getterOk || setter->IsNull() ||
5942 if (getterOk->IsFailure()) return getterOk; 5963 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes);
5943 } 5964 if (getterOk && setterOk) return;
5944
5945 MaybeObject* setterOk = heap->undefined_value();
5946 if (getterOk != heap->null_value() && !setter->IsNull()) {
5947 setterOk = DefineFastAccessor(name, ACCESSOR_SETTER, setter, attributes);
5948 if (setterOk->IsFailure()) return setterOk;
5949 }
5950
5951 if (getterOk != heap->null_value() && setterOk != heap->null_value()) {
5952 return heap->undefined_value();
5953 }
5954 } 5965 }
5955 5966
5956 AccessorPair* accessors; 5967 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name);
5957 MaybeObject* maybe_accessors = CreateAccessorPairFor(name); 5968 accessors->SetComponents(*getter, *setter);
5958 if (!maybe_accessors->To(&accessors)) return maybe_accessors;
5959 5969
5960 accessors->SetComponents(getter, setter); 5970 CALL_HEAP_FUNCTION_VOID(
5961 return SetPropertyCallback(name, accessors, attributes); 5971 object->GetIsolate(),
5972 object->SetPropertyCallback(*name, *accessors, attributes));
5962 } 5973 }
5963 5974
5964 5975
5965 bool JSObject::CanSetCallback(Name* name) { 5976 bool JSObject::CanSetCallback(Name* name) {
5966 ASSERT(!IsAccessCheckNeeded() || 5977 ASSERT(!IsAccessCheckNeeded() ||
5967 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); 5978 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET));
5968 5979
5969 // Check if there is an API defined callback object which prohibits 5980 // Check if there is an API defined callback object which prohibits
5970 // callback overwriting in this object or its prototype chain. 5981 // callback overwriting in this object or its prototype chain.
5971 // This mechanism is needed for instance in a browser setting, where 5982 // This mechanism is needed for instance in a browser setting, where
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
6053 6064
6054 return GetHeap()->undefined_value(); 6065 return GetHeap()->undefined_value();
6055 } 6066 }
6056 6067
6057 6068
6058 void JSObject::DefineAccessor(Handle<JSObject> object, 6069 void JSObject::DefineAccessor(Handle<JSObject> object,
6059 Handle<Name> name, 6070 Handle<Name> name,
6060 Handle<Object> getter, 6071 Handle<Object> getter,
6061 Handle<Object> setter, 6072 Handle<Object> setter,
6062 PropertyAttributes attributes) { 6073 PropertyAttributes attributes) {
6063 CALL_HEAP_FUNCTION_VOID( 6074 Isolate* isolate = object->GetIsolate();
6064 object->GetIsolate(),
6065 object->DefineAccessor(*name, *getter, *setter, attributes));
6066 }
6067
6068 MaybeObject* JSObject::DefineAccessor(Name* name_raw,
6069 Object* getter_raw,
6070 Object* setter_raw,
6071 PropertyAttributes attributes) {
6072 Isolate* isolate = GetIsolate();
6073 // Check access rights if needed. 6075 // Check access rights if needed.
6074 if (IsAccessCheckNeeded() && 6076 if (object->IsAccessCheckNeeded() &&
6075 !isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { 6077 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
6076 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 6078 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
6077 return isolate->heap()->undefined_value(); 6079 return;
6078 } 6080 }
6079 6081
6080 if (IsJSGlobalProxy()) { 6082 if (object->IsJSGlobalProxy()) {
6081 Object* proto = GetPrototype(); 6083 Handle<Object> proto(object->GetPrototype(), isolate);
6082 if (proto->IsNull()) return this; 6084 if (proto->IsNull()) return;
6083 ASSERT(proto->IsJSGlobalObject()); 6085 ASSERT(proto->IsJSGlobalObject());
6084 return JSObject::cast(proto)->DefineAccessor( 6086 DefineAccessor(
6085 name_raw, getter_raw, setter_raw, attributes); 6087 Handle<JSObject>::cast(proto), name, getter, setter, attributes);
6088 return;
6086 } 6089 }
6087 6090
6088 // Make sure that the top context does not change when doing callbacks or 6091 // Make sure that the top context does not change when doing callbacks or
6089 // interceptor calls. 6092 // interceptor calls.
6090 AssertNoContextChange ncc; 6093 AssertNoContextChange ncc;
6091 6094
6092 // Try to flatten before operating on the string. 6095 // Try to flatten before operating on the string.
6093 if (name_raw->IsString()) String::cast(name_raw)->TryFlatten(); 6096 if (name->IsString()) String::cast(*name)->TryFlatten();
6094 6097
6095 if (!CanSetCallback(name_raw)) return isolate->heap()->undefined_value(); 6098 if (!object->CanSetCallback(*name)) return;
6096
6097 // From this point on everything needs to be handlified.
6098 HandleScope scope(isolate);
6099 Handle<JSObject> self(this);
6100 Handle<Name> name(name_raw);
6101 Handle<Object> getter(getter_raw, isolate);
6102 Handle<Object> setter(setter_raw, isolate);
6103 6099
6104 uint32_t index = 0; 6100 uint32_t index = 0;
6105 bool is_element = name->AsArrayIndex(&index); 6101 bool is_element = name->AsArrayIndex(&index);
6106 6102
6107 Handle<Object> old_value = isolate->factory()->the_hole_value(); 6103 Handle<Object> old_value = isolate->factory()->the_hole_value();
6108 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); 6104 bool is_observed = FLAG_harmony_observation && object->map()->is_observed();
6109 bool preexists = false; 6105 bool preexists = false;
6110 if (is_observed) { 6106 if (is_observed) {
6111 if (is_element) { 6107 if (is_element) {
6112 preexists = HasLocalElement(index); 6108 preexists = object->HasLocalElement(index);
6113 if (preexists && self->GetLocalElementAccessorPair(index) == NULL) { 6109 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
6114 old_value = Object::GetElement(self, index); 6110 old_value = Object::GetElement(object, index);
6115 } 6111 }
6116 } else { 6112 } else {
6117 LookupResult lookup(isolate); 6113 LookupResult lookup(isolate);
6118 LocalLookup(*name, &lookup, true); 6114 object->LocalLookup(*name, &lookup, true);
6119 preexists = lookup.IsProperty(); 6115 preexists = lookup.IsProperty();
6120 if (preexists && lookup.IsDataProperty()) { 6116 if (preexists && lookup.IsDataProperty()) {
6121 old_value = Object::GetProperty(self, name); 6117 old_value = Object::GetProperty(object, name);
6122 } 6118 }
6123 } 6119 }
6124 } 6120 }
6125 6121
6126 MaybeObject* result = is_element ? 6122 if (is_element) {
6127 self->DefineElementAccessor(index, *getter, *setter, attributes) : 6123 DefineElementAccessor(object, index, getter, setter, attributes);
6128 self->DefinePropertyAccessor(*name, *getter, *setter, attributes); 6124 } else {
6129 6125 DefinePropertyAccessor(object, name, getter, setter, attributes);
6130 Handle<Object> hresult; 6126 }
6131 if (!result->ToHandle(&hresult, isolate)) return result;
6132 6127
6133 if (is_observed) { 6128 if (is_observed) {
6134 const char* type = preexists ? "reconfigured" : "new"; 6129 const char* type = preexists ? "reconfigured" : "new";
6135 EnqueueChangeRecord(self, type, name, old_value); 6130 EnqueueChangeRecord(object, type, name, old_value);
6136 } 6131 }
6137
6138 return *hresult;
6139 } 6132 }
6140 6133
6141 6134
6142 static MaybeObject* TryAccessorTransition(JSObject* self, 6135 static bool TryAccessorTransition(JSObject* self,
6143 Map* transitioned_map, 6136 Map* transitioned_map,
6144 int target_descriptor, 6137 int target_descriptor,
6145 AccessorComponent component, 6138 AccessorComponent component,
6146 Object* accessor, 6139 Object* accessor,
6147 PropertyAttributes attributes) { 6140 PropertyAttributes attributes) {
6148 DescriptorArray* descs = transitioned_map->instance_descriptors(); 6141 DescriptorArray* descs = transitioned_map->instance_descriptors();
6149 PropertyDetails details = descs->GetDetails(target_descriptor); 6142 PropertyDetails details = descs->GetDetails(target_descriptor);
6150 6143
6151 // If the transition target was not callbacks, fall back to the slow case. 6144 // If the transition target was not callbacks, fall back to the slow case.
6152 if (details.type() != CALLBACKS) return self->GetHeap()->null_value(); 6145 if (details.type() != CALLBACKS) return false;
6153 Object* descriptor = descs->GetCallbacksObject(target_descriptor); 6146 Object* descriptor = descs->GetCallbacksObject(target_descriptor);
6154 if (!descriptor->IsAccessorPair()) return self->GetHeap()->null_value(); 6147 if (!descriptor->IsAccessorPair()) return false;
6155 6148
6156 Object* target_accessor = AccessorPair::cast(descriptor)->get(component); 6149 Object* target_accessor = AccessorPair::cast(descriptor)->get(component);
6157 PropertyAttributes target_attributes = details.attributes(); 6150 PropertyAttributes target_attributes = details.attributes();
6158 6151
6159 // Reuse transition if adding same accessor with same attributes. 6152 // Reuse transition if adding same accessor with same attributes.
6160 if (target_accessor == accessor && target_attributes == attributes) { 6153 if (target_accessor == accessor && target_attributes == attributes) {
6161 self->set_map(transitioned_map); 6154 self->set_map(transitioned_map);
6162 return self; 6155 return true;
6163 } 6156 }
6164 6157
6165 // If either not the same accessor, or not the same attributes, fall back to 6158 // If either not the same accessor, or not the same attributes, fall back to
6166 // the slow case. 6159 // the slow case.
6167 return self->GetHeap()->null_value(); 6160 return false;
6168 } 6161 }
6169 6162
6170 6163
6171 MaybeObject* JSObject::DefineFastAccessor(Name* name, 6164 static MaybeObject* CopyInsertDescriptor(Map* map,
6172 AccessorComponent component, 6165 Name* name,
6173 Object* accessor, 6166 AccessorPair* accessors,
6174 PropertyAttributes attributes) { 6167 PropertyAttributes attributes) {
6168 CallbacksDescriptor new_accessors_desc(name, accessors, attributes);
6169 return map->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION);
6170 }
6171
6172
6173 static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
6174 Handle<Name> name,
6175 Handle<AccessorPair> accessors,
6176 PropertyAttributes attributes) {
6177 CALL_HEAP_FUNCTION(map->GetIsolate(),
6178 CopyInsertDescriptor(*map, *name, *accessors, attributes),
6179 Map);
6180 }
6181
6182
6183 bool JSObject::DefineFastAccessor(Handle<JSObject> object,
6184 Handle<Name> name,
6185 AccessorComponent component,
6186 Handle<Object> accessor,
6187 PropertyAttributes attributes) {
6175 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); 6188 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined());
6176 LookupResult result(GetIsolate()); 6189 Isolate* isolate = object->GetIsolate();
6177 LocalLookup(name, &result); 6190 LookupResult result(isolate);
6191 object->LocalLookup(*name, &result);
6178 6192
6179 if (result.IsFound() && !result.IsPropertyCallbacks()) { 6193 if (result.IsFound() && !result.IsPropertyCallbacks()) {
6180 return GetHeap()->null_value(); 6194 return false;
6181 } 6195 }
6182 6196
6183 // Return success if the same accessor with the same attributes already exist. 6197 // Return success if the same accessor with the same attributes already exist.
6184 AccessorPair* source_accessors = NULL; 6198 AccessorPair* source_accessors = NULL;
6185 if (result.IsPropertyCallbacks()) { 6199 if (result.IsPropertyCallbacks()) {
6186 Object* callback_value = result.GetCallbackObject(); 6200 Object* callback_value = result.GetCallbackObject();
6187 if (callback_value->IsAccessorPair()) { 6201 if (callback_value->IsAccessorPair()) {
6188 source_accessors = AccessorPair::cast(callback_value); 6202 source_accessors = AccessorPair::cast(callback_value);
6189 Object* entry = source_accessors->get(component); 6203 Object* entry = source_accessors->get(component);
6190 if (entry == accessor && result.GetAttributes() == attributes) { 6204 if (entry == *accessor && result.GetAttributes() == attributes) {
6191 return this; 6205 return true;
6192 } 6206 }
6193 } else { 6207 } else {
6194 return GetHeap()->null_value(); 6208 return false;
6195 } 6209 }
6196 6210
6197 int descriptor_number = result.GetDescriptorIndex(); 6211 int descriptor_number = result.GetDescriptorIndex();
6198 6212
6199 map()->LookupTransition(this, name, &result); 6213 object->map()->LookupTransition(*object, *name, &result);
6200 6214
6201 if (result.IsFound()) { 6215 if (result.IsFound()) {
6202 Map* target = result.GetTransitionTarget(); 6216 Map* target = result.GetTransitionTarget();
6203 ASSERT(target->NumberOfOwnDescriptors() == 6217 ASSERT(target->NumberOfOwnDescriptors() ==
6204 map()->NumberOfOwnDescriptors()); 6218 object->map()->NumberOfOwnDescriptors());
6205 // This works since descriptors are sorted in order of addition. 6219 // This works since descriptors are sorted in order of addition.
6206 ASSERT(map()->instance_descriptors()->GetKey(descriptor_number) == name); 6220 ASSERT(object->map()->instance_descriptors()->
6207 return TryAccessorTransition( 6221 GetKey(descriptor_number) == *name);
6208 this, target, descriptor_number, component, accessor, attributes); 6222 return TryAccessorTransition(*object, target, descriptor_number,
6223 component, *accessor, attributes);
6209 } 6224 }
6210 } else { 6225 } else {
6211 // If not, lookup a transition. 6226 // If not, lookup a transition.
6212 map()->LookupTransition(this, name, &result); 6227 object->map()->LookupTransition(*object, *name, &result);
6213 6228
6214 // If there is a transition, try to follow it. 6229 // If there is a transition, try to follow it.
6215 if (result.IsFound()) { 6230 if (result.IsFound()) {
6216 Map* target = result.GetTransitionTarget(); 6231 Map* target = result.GetTransitionTarget();
6217 int descriptor_number = target->LastAdded(); 6232 int descriptor_number = target->LastAdded();
6218 ASSERT(target->instance_descriptors()->GetKey(descriptor_number) 6233 ASSERT(target->instance_descriptors()->GetKey(descriptor_number)
6219 ->Equals(name)); 6234 ->Equals(*name));
6220 return TryAccessorTransition( 6235 return TryAccessorTransition(*object, target, descriptor_number,
6221 this, target, descriptor_number, component, accessor, attributes); 6236 component, *accessor, attributes);
6222 } 6237 }
6223 } 6238 }
6224 6239
6225 // If there is no transition yet, add a transition to the a new accessor pair 6240 // If there is no transition yet, add a transition to the a new accessor pair
6226 // containing the accessor. 6241 // containing the accessor. Allocate a new pair if there were no source
6227 AccessorPair* accessors; 6242 // accessors. Otherwise, copy the pair and modify the accessor.
6228 MaybeObject* maybe_accessors; 6243 Handle<AccessorPair> accessors = source_accessors != NULL
6229 6244 ? AccessorPair::Copy(Handle<AccessorPair>(source_accessors))
6230 // Allocate a new pair if there were no source accessors. Otherwise, copy the 6245 : isolate->factory()->NewAccessorPair();
6231 // pair and modify the accessor. 6246 accessors->set(component, *accessor);
6232 if (source_accessors != NULL) { 6247 Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()),
6233 maybe_accessors = source_accessors->Copy(); 6248 name, accessors, attributes);
6234 } else { 6249 object->set_map(*new_map);
6235 maybe_accessors = GetHeap()->AllocateAccessorPair(); 6250 return true;
6236 }
6237 if (!maybe_accessors->To(&accessors)) return maybe_accessors;
6238 accessors->set(component, accessor);
6239
6240 CallbacksDescriptor new_accessors_desc(name, accessors, attributes);
6241
6242 Map* new_map;
6243 MaybeObject* maybe_new_map =
6244 map()->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION);
6245 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
6246
6247 set_map(new_map);
6248 return this;
6249 } 6251 }
6250 6252
6251 6253
6252 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { 6254 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) {
6253 Isolate* isolate = GetIsolate(); 6255 Isolate* isolate = GetIsolate();
6254 Name* name = Name::cast(info->name()); 6256 Name* name = Name::cast(info->name());
6255 // Check access rights if needed. 6257 // Check access rights if needed.
6256 if (IsAccessCheckNeeded() && 6258 if (IsAccessCheckNeeded() &&
6257 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { 6259 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
6258 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 6260 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
6682 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); 6684 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
6683 DescriptorArray* new_descriptors; 6685 DescriptorArray* new_descriptors;
6684 MaybeObject* maybe_descriptors = 6686 MaybeObject* maybe_descriptors =
6685 descriptors->CopyUpTo(number_of_own_descriptors); 6687 descriptors->CopyUpTo(number_of_own_descriptors);
6686 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 6688 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
6687 6689
6688 return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION); 6690 return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION);
6689 } 6691 }
6690 6692
6691 6693
6694 Handle<Map> Map::Copy(Handle<Map> map) {
6695 CALL_HEAP_FUNCTION(map->GetIsolate(), map->Copy(), Map);
6696 }
6697
6698
6692 MaybeObject* Map::Copy() { 6699 MaybeObject* Map::Copy() {
6693 DescriptorArray* descriptors = instance_descriptors(); 6700 DescriptorArray* descriptors = instance_descriptors();
6694 DescriptorArray* new_descriptors; 6701 DescriptorArray* new_descriptors;
6695 int number_of_own_descriptors = NumberOfOwnDescriptors(); 6702 int number_of_own_descriptors = NumberOfOwnDescriptors();
6696 MaybeObject* maybe_descriptors = 6703 MaybeObject* maybe_descriptors =
6697 descriptors->CopyUpTo(number_of_own_descriptors); 6704 descriptors->CopyUpTo(number_of_own_descriptors);
6698 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 6705 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
6699 6706
6700 return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION); 6707 return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION);
6701 } 6708 }
(...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after
7813 } 7820 }
7814 if (child_hash <= parent_hash) break; 7821 if (child_hash <= parent_hash) break;
7815 SwapSortedKeys(parent_index, child_index); 7822 SwapSortedKeys(parent_index, child_index);
7816 parent_index = child_index; 7823 parent_index = child_index;
7817 } 7824 }
7818 } 7825 }
7819 ASSERT(IsSortedNoDuplicates()); 7826 ASSERT(IsSortedNoDuplicates());
7820 } 7827 }
7821 7828
7822 7829
7823 MaybeObject* AccessorPair::Copy() { 7830 Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) {
7824 Heap* heap = GetHeap(); 7831 Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair();
7825 AccessorPair* copy; 7832 copy->set_getter(pair->getter());
7826 MaybeObject* maybe_copy = heap->AllocateAccessorPair(); 7833 copy->set_setter(pair->setter());
7827 if (!maybe_copy->To(&copy)) return maybe_copy;
7828
7829 copy->set_getter(getter());
7830 copy->set_setter(setter());
7831 return copy; 7834 return copy;
7832 } 7835 }
7833 7836
7834 7837
7835 Object* AccessorPair::GetComponent(AccessorComponent component) { 7838 Object* AccessorPair::GetComponent(AccessorComponent component) {
7836 Object* accessor = get(component); 7839 Object* accessor = get(component);
7837 return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor; 7840 return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor;
7838 } 7841 }
7839 7842
7840 7843
(...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after
8855 AllocationSiteInfo* info = AllocationSiteInfo::cast( 8858 AllocationSiteInfo* info = AllocationSiteInfo::cast(
8856 reinterpret_cast<Object*>(ptr_end + 1)); 8859 reinterpret_cast<Object*>(ptr_end + 1));
8857 return info; 8860 return info;
8858 } 8861 }
8859 } 8862 }
8860 } 8863 }
8861 return NULL; 8864 return NULL;
8862 } 8865 }
8863 8866
8864 8867
8865 bool AllocationSiteInfo::GetElementsKindPayload(ElementsKind* kind) {
8866 ASSERT(kind != NULL);
8867 if (payload()->IsCell()) {
8868 Cell* cell = Cell::cast(payload());
8869 Object* cell_contents = cell->value();
8870 if (cell_contents->IsSmi()) {
8871 *kind = static_cast<ElementsKind>(
8872 Smi::cast(cell_contents)->value());
8873 return true;
8874 }
8875 }
8876 return false;
8877 }
8878
8879
8880 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { 8868 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
8881 // For array indexes mix the length into the hash as an array index could 8869 // For array indexes mix the length into the hash as an array index could
8882 // be zero. 8870 // be zero.
8883 ASSERT(length > 0); 8871 ASSERT(length > 0);
8884 ASSERT(length <= String::kMaxArrayIndexSize); 8872 ASSERT(length <= String::kMaxArrayIndexSize);
8885 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 8873 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
8886 (1 << String::kArrayIndexValueBits)); 8874 (1 << String::kArrayIndexValueBits));
8887 8875
8888 value <<= String::kHashShift; 8876 value <<= String::kHashShift;
8889 value |= length << String::kArrayIndexHashLengthShift; 8877 value |= length << String::kArrayIndexHashLengthShift;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
9133 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { 9121 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) {
9134 // Iterate over all fields in the body but take care in dealing with 9122 // Iterate over all fields in the body but take care in dealing with
9135 // the code entry. 9123 // the code entry.
9136 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); 9124 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset);
9137 v->VisitCodeEntry(this->address() + kCodeEntryOffset); 9125 v->VisitCodeEntry(this->address() + kCodeEntryOffset);
9138 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); 9126 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size);
9139 } 9127 }
9140 9128
9141 9129
9142 void JSFunction::MarkForLazyRecompilation() { 9130 void JSFunction::MarkForLazyRecompilation() {
9143 ASSERT(is_compiled() && !IsOptimized()); 9131 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints());
9132 ASSERT(!IsOptimized());
9144 ASSERT(shared()->allows_lazy_compilation() || 9133 ASSERT(shared()->allows_lazy_compilation() ||
9145 code()->optimizable()); 9134 code()->optimizable());
9146 set_code_no_write_barrier( 9135 set_code_no_write_barrier(
9147 GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile)); 9136 GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile));
9148 // No write barrier required, since the builtin is part of the root set. 9137 // No write barrier required, since the builtin is part of the root set.
9149 } 9138 }
9150 9139
9151 9140
9152 void JSFunction::MarkForParallelRecompilation() { 9141 void JSFunction::MarkForParallelRecompilation() {
9153 ASSERT(is_compiled() && !IsOptimized()); 9142 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints());
9143 ASSERT(!IsOptimized());
9154 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); 9144 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable());
9155 if (!FLAG_parallel_recompilation) { 9145 if (!FLAG_parallel_recompilation) {
9156 JSFunction::MarkForLazyRecompilation(); 9146 JSFunction::MarkForLazyRecompilation();
9157 return; 9147 return;
9158 } 9148 }
9159 if (FLAG_trace_parallel_recompilation) { 9149 if (FLAG_trace_parallel_recompilation) {
9160 PrintF(" ** Marking "); 9150 PrintF(" ** Marking ");
9161 PrintName(); 9151 PrintName();
9162 PrintF(" for parallel recompilation.\n"); 9152 PrintF(" for parallel recompilation.\n");
9163 } 9153 }
9164 set_code_no_write_barrier( 9154 set_code_no_write_barrier(
9165 GetIsolate()->builtins()->builtin(Builtins::kParallelRecompile)); 9155 GetIsolate()->builtins()->builtin(Builtins::kParallelRecompile));
9166 // No write barrier required, since the builtin is part of the root set. 9156 // No write barrier required, since the builtin is part of the root set.
9167 } 9157 }
9168 9158
9169 9159
9170 void JSFunction::MarkForInstallingRecompiledCode() { 9160 void JSFunction::MarkForInstallingRecompiledCode() {
9171 ASSERT(is_compiled() && !IsOptimized()); 9161 // The debugger could have switched the builtin to lazy compile.
9162 // In that case, simply carry on. It will be dealt with later.
9163 ASSERT(!IsOptimized());
9172 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); 9164 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable());
9173 ASSERT(FLAG_parallel_recompilation); 9165 ASSERT(FLAG_parallel_recompilation);
9174 set_code_no_write_barrier( 9166 set_code_no_write_barrier(
9175 GetIsolate()->builtins()->builtin(Builtins::kInstallRecompiledCode)); 9167 GetIsolate()->builtins()->builtin(Builtins::kInstallRecompiledCode));
9176 // No write barrier required, since the builtin is part of the root set. 9168 // No write barrier required, since the builtin is part of the root set.
9177 } 9169 }
9178 9170
9179 9171
9180 void JSFunction::MarkInRecompileQueue() { 9172 void JSFunction::MarkInRecompileQueue() {
9181 ASSERT(is_compiled() && !IsOptimized()); 9173 // We can only arrive here via the parallel-recompilation builtin. If
9174 // break points were set, the code would point to the lazy-compile builtin.
9175 ASSERT(!GetIsolate()->DebuggerHasBreakPoints());
9176 ASSERT(IsMarkedForParallelRecompilation() && !IsOptimized());
9182 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); 9177 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable());
9183 ASSERT(FLAG_parallel_recompilation); 9178 ASSERT(FLAG_parallel_recompilation);
9184 if (FLAG_trace_parallel_recompilation) { 9179 if (FLAG_trace_parallel_recompilation) {
9185 PrintF(" ** Queueing "); 9180 PrintF(" ** Queueing ");
9186 PrintName(); 9181 PrintName();
9187 PrintF(" for parallel recompilation.\n"); 9182 PrintF(" for parallel recompilation.\n");
9188 } 9183 }
9189 set_code_no_write_barrier( 9184 set_code_no_write_barrier(
9190 GetIsolate()->builtins()->builtin(Builtins::kInRecompileQueue)); 9185 GetIsolate()->builtins()->builtin(Builtins::kInRecompileQueue));
9191 // No write barrier required, since the builtin is part of the root set. 9186 // No write barrier required, since the builtin is part of the root set.
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
9389 if (!shared_info->script()->IsScript()) return false; 9384 if (!shared_info->script()->IsScript()) return false;
9390 if (shared_info->optimization_disabled()) return false; 9385 if (shared_info->optimization_disabled()) return false;
9391 Code* code = shared_info->code(); 9386 Code* code = shared_info->code();
9392 if (code->kind() == Code::OPTIMIZED_FUNCTION) return true; 9387 if (code->kind() == Code::OPTIMIZED_FUNCTION) return true;
9393 // If we never ran this (unlikely) then lets try to optimize it. 9388 // If we never ran this (unlikely) then lets try to optimize it.
9394 if (code->kind() != Code::FUNCTION) return true; 9389 if (code->kind() != Code::FUNCTION) return true;
9395 return code->optimizable(); 9390 return code->optimizable();
9396 } 9391 }
9397 9392
9398 9393
9394 void JSObject::OptimizeAsPrototype(Handle<JSObject> object) {
9395 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), object->OptimizeAsPrototype());
9396 }
9397
9398
9399 MaybeObject* JSObject::OptimizeAsPrototype() { 9399 MaybeObject* JSObject::OptimizeAsPrototype() {
9400 if (IsGlobalObject()) return this; 9400 if (IsGlobalObject()) return this;
9401 9401
9402 // Make sure prototypes are fast objects and their maps have the bit set 9402 // Make sure prototypes are fast objects and their maps have the bit set
9403 // so they remain fast. 9403 // so they remain fast.
9404 if (!HasFastProperties()) { 9404 if (!HasFastProperties()) {
9405 MaybeObject* new_proto = TransformToFastProperties(0); 9405 MaybeObject* new_proto = TransformToFastProperties(0);
9406 if (new_proto->IsFailure()) return new_proto; 9406 if (new_proto->IsFailure()) return new_proto;
9407 ASSERT(new_proto == this); 9407 ASSERT(new_proto == this);
9408 } 9408 }
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
9956 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && 9956 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
9957 rinfo->IsPatchedReturnSequence()) || 9957 rinfo->IsPatchedReturnSequence()) ||
9958 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && 9958 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
9959 rinfo->IsPatchedDebugBreakSlotSequence())); 9959 rinfo->IsPatchedDebugBreakSlotSequence()));
9960 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); 9960 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
9961 Object* old_target = target; 9961 Object* old_target = target;
9962 VisitPointer(&target); 9962 VisitPointer(&target);
9963 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. 9963 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target.
9964 } 9964 }
9965 9965
9966
9966 void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) { 9967 void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) {
9967 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); 9968 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
9968 VisitPointer(rinfo->target_object_address()); 9969 VisitPointer(rinfo->target_object_address());
9969 } 9970 }
9970 9971
9972
9971 void ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) { 9973 void ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) {
9972 Address* p = rinfo->target_reference_address(); 9974 Address* p = rinfo->target_reference_address();
9973 VisitExternalReferences(p, p + 1); 9975 VisitExternalReferences(p, p + 1);
9974 } 9976 }
9975 9977
9978
9976 byte Code::compare_nil_state() { 9979 byte Code::compare_nil_state() {
9977 ASSERT(is_compare_nil_ic_stub()); 9980 ASSERT(is_compare_nil_ic_stub());
9978 return CompareNilICStub::ExtractTypesFromExtraICState( 9981 return CompareNilICStub::ExtractTypesFromExtraICState(
9979 extended_extra_ic_state()); 9982 extended_extra_ic_state());
9980 } 9983 }
9981 9984
9985
9982 byte Code::compare_nil_value() { 9986 byte Code::compare_nil_value() {
9983 ASSERT(is_compare_nil_ic_stub()); 9987 ASSERT(is_compare_nil_ic_stub());
9984 return CompareNilICStub::ExtractNilValueFromExtraICState( 9988 return CompareNilICStub::ExtractNilValueFromExtraICState(
9985 extended_extra_ic_state()); 9989 extended_extra_ic_state());
9986 } 9990 }
9987 9991
9988 9992
9989 void Code::InvalidateRelocation() { 9993 void Code::InvalidateRelocation() {
9990 set_relocation_info(GetHeap()->empty_byte_array()); 9994 set_relocation_info(GetHeap()->empty_byte_array());
9991 } 9995 }
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
10243 10247
10244 10248
10245 void Code::ClearTypeFeedbackCells(Heap* heap) { 10249 void Code::ClearTypeFeedbackCells(Heap* heap) {
10246 if (kind() != FUNCTION) return; 10250 if (kind() != FUNCTION) return;
10247 Object* raw_info = type_feedback_info(); 10251 Object* raw_info = type_feedback_info();
10248 if (raw_info->IsTypeFeedbackInfo()) { 10252 if (raw_info->IsTypeFeedbackInfo()) {
10249 TypeFeedbackCells* type_feedback_cells = 10253 TypeFeedbackCells* type_feedback_cells =
10250 TypeFeedbackInfo::cast(raw_info)->type_feedback_cells(); 10254 TypeFeedbackInfo::cast(raw_info)->type_feedback_cells();
10251 for (int i = 0; i < type_feedback_cells->CellCount(); i++) { 10255 for (int i = 0; i < type_feedback_cells->CellCount(); i++) {
10252 Cell* cell = type_feedback_cells->GetCell(i); 10256 Cell* cell = type_feedback_cells->GetCell(i);
10253 cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap)); 10257 // Don't clear AllocationSites
10258 Object* value = cell->value();
10259 if (value == NULL || !value->IsAllocationSite()) {
10260 cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap));
10261 }
10254 } 10262 }
10255 } 10263 }
10256 } 10264 }
10257 10265
10258 10266
10259 bool Code::allowed_in_shared_map_code_cache() { 10267 bool Code::allowed_in_shared_map_code_cache() {
10260 return is_keyed_load_stub() || is_keyed_store_stub() || 10268 return is_keyed_load_stub() || is_keyed_store_stub() ||
10261 (is_compare_ic_stub() && 10269 (is_compare_ic_stub() &&
10262 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT); 10270 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT);
10263 } 10271 }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
10374 GetIsolate(), info->target_address(), Deoptimizer::SOFT))) { 10382 GetIsolate(), info->target_address(), Deoptimizer::SOFT))) {
10375 CHECK(RelocInfo::IsRuntimeEntry(info->rmode())); 10383 CHECK(RelocInfo::IsRuntimeEntry(info->rmode()));
10376 PrintF(" %s\n", last_comment); 10384 PrintF(" %s\n", last_comment);
10377 return; 10385 return;
10378 } 10386 }
10379 } 10387 }
10380 } 10388 }
10381 } 10389 }
10382 10390
10383 10391
10392 bool Code::CanDeoptAt(Address pc) {
10393 DeoptimizationInputData* deopt_data =
10394 DeoptimizationInputData::cast(deoptimization_data());
10395 Address code_start_address = instruction_start();
10396 for (int i = 0; i < deopt_data->DeoptCount(); i++) {
10397 if (deopt_data->Pc(i)->value() == -1) continue;
10398 Address address = code_start_address + deopt_data->Pc(i)->value();
10399 if (address == pc) return true;
10400 }
10401 return false;
10402 }
10403
10404
10384 // Identify kind of code. 10405 // Identify kind of code.
10385 const char* Code::Kind2String(Kind kind) { 10406 const char* Code::Kind2String(Kind kind) {
10386 switch (kind) { 10407 switch (kind) {
10387 #define CASE(name) case name: return #name; 10408 #define CASE(name) case name: return #name;
10388 CODE_KIND_LIST(CASE) 10409 CODE_KIND_LIST(CASE)
10389 #undef CASE 10410 #undef CASE
10390 case NUMBER_OF_KINDS: break; 10411 case NUMBER_OF_KINDS: break;
10391 } 10412 }
10392 UNREACHABLE(); 10413 UNREACHABLE();
10393 return NULL; 10414 return NULL;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
10592 case INTERCEPTOR: return "INTERCEPTOR"; 10613 case INTERCEPTOR: return "INTERCEPTOR";
10593 case MAP_TRANSITION: return "MAP_TRANSITION"; 10614 case MAP_TRANSITION: return "MAP_TRANSITION";
10594 case NONEXISTENT: return "NONEXISTENT"; 10615 case NONEXISTENT: return "NONEXISTENT";
10595 } 10616 }
10596 UNREACHABLE(); // keep the compiler happy 10617 UNREACHABLE(); // keep the compiler happy
10597 return NULL; 10618 return NULL;
10598 } 10619 }
10599 10620
10600 10621
10601 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { 10622 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) {
10623 PrintF(out, "extra_ic_state = ");
10602 const char* name = NULL; 10624 const char* name = NULL;
10603 switch (kind) { 10625 switch (kind) {
10604 case CALL_IC: 10626 case CALL_IC:
10605 if (extra == STRING_INDEX_OUT_OF_BOUNDS) { 10627 if (extra == STRING_INDEX_OUT_OF_BOUNDS) {
10606 name = "STRING_INDEX_OUT_OF_BOUNDS"; 10628 name = "STRING_INDEX_OUT_OF_BOUNDS";
10607 } 10629 }
10608 break; 10630 break;
10609 case STORE_IC: 10631 case STORE_IC:
10610 case KEYED_STORE_IC: 10632 case KEYED_STORE_IC:
10611 if (extra == kStrictMode) { 10633 if (extra == kStrictMode) {
10612 name = "STRICT"; 10634 name = "STRICT";
10613 } 10635 }
10614 break; 10636 break;
10615 default: 10637 default:
10616 break; 10638 break;
10617 } 10639 }
10618 if (name != NULL) { 10640 if (name != NULL) {
10619 PrintF(out, "extra_ic_state = %s\n", name); 10641 PrintF(out, "%s\n", name);
10620 } else { 10642 } else {
10621 PrintF(out, "extra_ic_state = %d\n", extra); 10643 PrintF(out, "%d\n", extra);
10622 } 10644 }
10623 } 10645 }
10624 10646
10625 10647
10626 void Code::Disassemble(const char* name, FILE* out) { 10648 void Code::Disassemble(const char* name, FILE* out) {
10627 PrintF(out, "kind = %s\n", Kind2String(kind())); 10649 PrintF(out, "kind = %s\n", Kind2String(kind()));
10628 if (is_inline_cache_stub()) { 10650 if (is_inline_cache_stub()) {
10629 PrintF(out, "ic_state = %s\n", ICState2String(ic_state())); 10651 PrintF(out, "ic_state = %s\n", ICState2String(ic_state()));
10630 PrintExtraICState(out, kind(), extra_ic_state()); 10652 PrintExtraICState(out, kind(), needs_extended_extra_ic_state(kind()) ?
10653 extended_extra_ic_state() : extra_ic_state());
10631 if (ic_state() == MONOMORPHIC) { 10654 if (ic_state() == MONOMORPHIC) {
10632 PrintF(out, "type = %s\n", StubType2String(type())); 10655 PrintF(out, "type = %s\n", StubType2String(type()));
10633 } 10656 }
10634 if (is_call_stub() || is_keyed_call_stub()) { 10657 if (is_call_stub() || is_keyed_call_stub()) {
10635 PrintF(out, "argc = %d\n", arguments_count()); 10658 PrintF(out, "argc = %d\n", arguments_count());
10636 } 10659 }
10637 if (is_compare_ic_stub()) { 10660 if (is_compare_ic_stub()) {
10638 ASSERT(major_key() == CodeStub::CompareIC); 10661 ASSERT(major_key() == CodeStub::CompareIC);
10639 CompareIC::State left_state, right_state, handler_state; 10662 CompareIC::State left_state, right_state, handler_state;
10640 Token::Value op; 10663 Token::Value op;
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
11001 isolate->factory()->NewNumberFromUint(delete_count), 11024 isolate->factory()->NewNumberFromUint(delete_count),
11002 NONE, kNonStrictMode); 11025 NONE, kNonStrictMode);
11003 } 11026 }
11004 11027
11005 EnqueueSpliceRecord(self, index, deleted, add_count); 11028 EnqueueSpliceRecord(self, index, deleted, add_count);
11006 11029
11007 return *hresult; 11030 return *hresult;
11008 } 11031 }
11009 11032
11010 11033
11011 Map* Map::GetPrototypeTransition(Object* prototype) { 11034 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map,
11012 FixedArray* cache = GetPrototypeTransitions(); 11035 Handle<Object> prototype) {
11013 int number_of_transitions = NumberOfProtoTransitions(); 11036 FixedArray* cache = map->GetPrototypeTransitions();
11037 int number_of_transitions = map->NumberOfProtoTransitions();
11014 const int proto_offset = 11038 const int proto_offset =
11015 kProtoTransitionHeaderSize + kProtoTransitionPrototypeOffset; 11039 kProtoTransitionHeaderSize + kProtoTransitionPrototypeOffset;
11016 const int map_offset = kProtoTransitionHeaderSize + kProtoTransitionMapOffset; 11040 const int map_offset = kProtoTransitionHeaderSize + kProtoTransitionMapOffset;
11017 const int step = kProtoTransitionElementsPerEntry; 11041 const int step = kProtoTransitionElementsPerEntry;
11018 for (int i = 0; i < number_of_transitions; i++) { 11042 for (int i = 0; i < number_of_transitions; i++) {
11019 if (cache->get(proto_offset + i * step) == prototype) { 11043 if (cache->get(proto_offset + i * step) == *prototype) {
11020 Object* map = cache->get(map_offset + i * step); 11044 Object* result = cache->get(map_offset + i * step);
11021 return Map::cast(map); 11045 return Handle<Map>(Map::cast(result));
11022 } 11046 }
11023 } 11047 }
11024 return NULL; 11048 return Handle<Map>();
11025 } 11049 }
11026 11050
11027 11051
11028 MaybeObject* Map::PutPrototypeTransition(Object* prototype, Map* map) { 11052 Handle<Map> Map::PutPrototypeTransition(Handle<Map> map,
11029 ASSERT(map->IsMap()); 11053 Handle<Object> prototype,
11030 ASSERT(HeapObject::cast(prototype)->map()->IsMap()); 11054 Handle<Map> target_map) {
11055 ASSERT(target_map->IsMap());
11056 ASSERT(HeapObject::cast(*prototype)->map()->IsMap());
11031 // Don't cache prototype transition if this map is shared. 11057 // Don't cache prototype transition if this map is shared.
11032 if (is_shared() || !FLAG_cache_prototype_transitions) return this; 11058 if (map->is_shared() || !FLAG_cache_prototype_transitions) return map;
11033
11034 FixedArray* cache = GetPrototypeTransitions();
11035 11059
11036 const int step = kProtoTransitionElementsPerEntry; 11060 const int step = kProtoTransitionElementsPerEntry;
11037 const int header = kProtoTransitionHeaderSize; 11061 const int header = kProtoTransitionHeaderSize;
11038 11062
11063 Handle<FixedArray> cache(map->GetPrototypeTransitions());
11039 int capacity = (cache->length() - header) / step; 11064 int capacity = (cache->length() - header) / step;
11040 11065 int transitions = map->NumberOfProtoTransitions() + 1;
11041 int transitions = NumberOfProtoTransitions() + 1;
11042 11066
11043 if (transitions > capacity) { 11067 if (transitions > capacity) {
11044 if (capacity > kMaxCachedPrototypeTransitions) return this; 11068 if (capacity > kMaxCachedPrototypeTransitions) return map;
11045 11069
11046 FixedArray* new_cache;
11047 // Grow array by factor 2 over and above what we need. 11070 // Grow array by factor 2 over and above what we need.
11048 { MaybeObject* maybe_cache = 11071 Factory* factory = map->GetIsolate()->factory();
11049 GetHeap()->AllocateFixedArray(transitions * 2 * step + header); 11072 cache = factory->CopySizeFixedArray(cache, transitions * 2 * step + header);
11050 if (!maybe_cache->To(&new_cache)) return maybe_cache;
11051 }
11052 11073
11053 for (int i = 0; i < capacity * step; i++) { 11074 CALL_AND_RETRY_OR_DIE(map->GetIsolate(),
11054 new_cache->set(i + header, cache->get(i + header)); 11075 map->SetPrototypeTransitions(*cache),
11055 } 11076 break,
11056 cache = new_cache; 11077 return Handle<Map>());
11057 MaybeObject* set_result = SetPrototypeTransitions(cache);
11058 if (set_result->IsFailure()) return set_result;
11059 } 11078 }
11060 11079
11061 int last = transitions - 1; 11080 // Reload number of transitions as GC might shrink them.
11081 int last = map->NumberOfProtoTransitions();
11082 int entry = header + last * step;
11062 11083
11063 cache->set(header + last * step + kProtoTransitionPrototypeOffset, prototype); 11084 cache->set(entry + kProtoTransitionPrototypeOffset, *prototype);
11064 cache->set(header + last * step + kProtoTransitionMapOffset, map); 11085 cache->set(entry + kProtoTransitionMapOffset, *target_map);
11065 SetNumberOfProtoTransitions(transitions); 11086 map->SetNumberOfProtoTransitions(transitions);
11066 11087
11067 return cache; 11088 return map;
11068 } 11089 }
11069 11090
11070 11091
11071 void Map::ZapTransitions() { 11092 void Map::ZapTransitions() {
11072 TransitionArray* transition_array = transitions(); 11093 TransitionArray* transition_array = transitions();
11073 // TODO(mstarzinger): Temporarily use a slower version instead of the faster 11094 // TODO(mstarzinger): Temporarily use a slower version instead of the faster
11074 // MemsetPointer to investigate a crasher. Switch back to MemsetPointer. 11095 // MemsetPointer to investigate a crasher. Switch back to MemsetPointer.
11075 Object** data = transition_array->data_start(); 11096 Object** data = transition_array->data_start();
11076 Object* the_hole = GetHeap()->the_hole_value(); 11097 Object* the_hole = GetHeap()->the_hole_value();
11077 int length = transition_array->length(); 11098 int length = transition_array->length();
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
11280 int removed = end - start; 11301 int removed = end - start;
11281 for (int i = code_entries - removed; i < code_entries; i++) { 11302 for (int i = code_entries - removed; i < code_entries; i++) {
11282 clear_at(i); 11303 clear_at(i);
11283 } 11304 }
11284 set_number_of_entries(group, 0); 11305 set_number_of_entries(group, 0);
11285 DeoptimizeDependentCodeFilter filter; 11306 DeoptimizeDependentCodeFilter filter;
11286 Deoptimizer::DeoptimizeAllFunctionsWith(isolate, &filter); 11307 Deoptimizer::DeoptimizeAllFunctionsWith(isolate, &filter);
11287 } 11308 }
11288 11309
11289 11310
11290 MaybeObject* JSReceiver::SetPrototype(Object* value, 11311 Handle<Object> JSObject::SetPrototype(Handle<JSObject> object,
11312 Handle<Object> value,
11291 bool skip_hidden_prototypes) { 11313 bool skip_hidden_prototypes) {
11292 #ifdef DEBUG 11314 #ifdef DEBUG
11293 int size = Size(); 11315 int size = object->Size();
11294 #endif 11316 #endif
11295 11317
11296 Isolate* isolate = GetIsolate(); 11318 Isolate* isolate = object->GetIsolate();
11297 Heap* heap = isolate->heap(); 11319 Heap* heap = isolate->heap();
11298 // Silently ignore the change if value is not a JSObject or null. 11320 // Silently ignore the change if value is not a JSObject or null.
11299 // SpiderMonkey behaves this way. 11321 // SpiderMonkey behaves this way.
11300 if (!value->IsJSReceiver() && !value->IsNull()) return value; 11322 if (!value->IsJSReceiver() && !value->IsNull()) return value;
11301 11323
11302 // From 8.6.2 Object Internal Methods 11324 // From 8.6.2 Object Internal Methods
11303 // ... 11325 // ...
11304 // In addition, if [[Extensible]] is false the value of the [[Class]] and 11326 // In addition, if [[Extensible]] is false the value of the [[Class]] and
11305 // [[Prototype]] internal properties of the object may not be modified. 11327 // [[Prototype]] internal properties of the object may not be modified.
11306 // ... 11328 // ...
11307 // Implementation specific extensions that modify [[Class]], [[Prototype]] 11329 // Implementation specific extensions that modify [[Class]], [[Prototype]]
11308 // or [[Extensible]] must not violate the invariants defined in the preceding 11330 // or [[Extensible]] must not violate the invariants defined in the preceding
11309 // paragraph. 11331 // paragraph.
11310 if (!this->map()->is_extensible()) { 11332 if (!object->map()->is_extensible()) {
11311 HandleScope scope(isolate); 11333 Handle<Object> args[] = { object };
11312 Handle<Object> handle(this, isolate); 11334 Handle<Object> error = isolate->factory()->NewTypeError(
11313 return isolate->Throw( 11335 "non_extensible_proto", HandleVector(args, ARRAY_SIZE(args)));
11314 *isolate->factory()->NewTypeError("non_extensible_proto", 11336 isolate->Throw(*error);
11315 HandleVector<Object>(&handle, 1))); 11337 return Handle<Object>();
11316 } 11338 }
11317 11339
11318 // Before we can set the prototype we need to be sure 11340 // Before we can set the prototype we need to be sure
11319 // prototype cycles are prevented. 11341 // prototype cycles are prevented.
11320 // It is sufficient to validate that the receiver is not in the new prototype 11342 // It is sufficient to validate that the receiver is not in the new prototype
11321 // chain. 11343 // chain.
11322 for (Object* pt = value; 11344 for (Object* pt = *value;
11323 pt != heap->null_value(); 11345 pt != heap->null_value();
11324 pt = pt->GetPrototype(isolate)) { 11346 pt = pt->GetPrototype(isolate)) {
11325 if (JSReceiver::cast(pt) == this) { 11347 if (JSReceiver::cast(pt) == *object) {
11326 // Cycle detected. 11348 // Cycle detected.
11327 HandleScope scope(isolate); 11349 Handle<Object> error = isolate->factory()->NewError(
11328 return isolate->Throw( 11350 "cyclic_proto", HandleVector<Object>(NULL, 0));
11329 *isolate->factory()->NewError("cyclic_proto", 11351 isolate->Throw(*error);
11330 HandleVector<Object>(NULL, 0))); 11352 return Handle<Object>();
11331 } 11353 }
11332 } 11354 }
11333 11355
11334 JSReceiver* real_receiver = this; 11356 Handle<JSObject> real_receiver = object;
11335 11357
11336 if (skip_hidden_prototypes) { 11358 if (skip_hidden_prototypes) {
11337 // Find the first object in the chain whose prototype object is not 11359 // Find the first object in the chain whose prototype object is not
11338 // hidden and set the new prototype on that object. 11360 // hidden and set the new prototype on that object.
11339 Object* current_proto = real_receiver->GetPrototype(); 11361 Object* current_proto = real_receiver->GetPrototype();
11340 while (current_proto->IsJSObject() && 11362 while (current_proto->IsJSObject() &&
11341 JSReceiver::cast(current_proto)->map()->is_hidden_prototype()) { 11363 JSObject::cast(current_proto)->map()->is_hidden_prototype()) {
11342 real_receiver = JSReceiver::cast(current_proto); 11364 real_receiver = handle(JSObject::cast(current_proto), isolate);
11343 current_proto = current_proto->GetPrototype(isolate); 11365 current_proto = current_proto->GetPrototype(isolate);
11344 } 11366 }
11345 } 11367 }
11346 11368
11347 // Set the new prototype of the object. 11369 // Set the new prototype of the object.
11348 Map* map = real_receiver->map(); 11370 Handle<Map> map(real_receiver->map());
11349 11371
11350 // Nothing to do if prototype is already set. 11372 // Nothing to do if prototype is already set.
11351 if (map->prototype() == value) return value; 11373 if (map->prototype() == *value) return value;
11352 11374
11353 if (value->IsJSObject()) { 11375 if (value->IsJSObject()) {
11354 MaybeObject* ok = JSObject::cast(value)->OptimizeAsPrototype(); 11376 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
11355 if (ok->IsFailure()) return ok;
11356 } 11377 }
11357 11378
11358 Map* new_map = map->GetPrototypeTransition(value); 11379 Handle<Map> new_map = Map::GetPrototypeTransition(map, value);
11359 if (new_map == NULL) { 11380 if (new_map.is_null()) {
11360 MaybeObject* maybe_new_map = map->Copy(); 11381 new_map = Map::Copy(map);
11361 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 11382 Map::PutPrototypeTransition(map, value, new_map);
11362 11383 new_map->set_prototype(*value);
11363 MaybeObject* maybe_new_cache =
11364 map->PutPrototypeTransition(value, new_map);
11365 if (maybe_new_cache->IsFailure()) return maybe_new_cache;
11366
11367 new_map->set_prototype(value);
11368 } 11384 }
11369 ASSERT(new_map->prototype() == value); 11385 ASSERT(new_map->prototype() == *value);
11370 real_receiver->set_map(new_map); 11386 real_receiver->set_map(*new_map);
11371 11387
11372 heap->ClearInstanceofCache(); 11388 heap->ClearInstanceofCache();
11373 ASSERT(size == Size()); 11389 ASSERT(size == object->Size());
11374 return value; 11390 return value;
11375 } 11391 }
11376 11392
11377 11393
11378 MaybeObject* JSObject::EnsureCanContainElements(Arguments* args, 11394 MaybeObject* JSObject::EnsureCanContainElements(Arguments* args,
11379 uint32_t first_arg, 11395 uint32_t first_arg,
11380 uint32_t arg_count, 11396 uint32_t arg_count,
11381 EnsureElementsMode mode) { 11397 EnsureElementsMode mode) {
11382 // Elements in |Arguments| are ordered backwards (because they're on the 11398 // Elements in |Arguments| are ordered backwards (because they're on the
11383 // stack), but the method that's called here iterates over them in forward 11399 // stack), but the method that's called here iterates over them in forward
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
11700 check_prototype); 11716 check_prototype);
11701 } 11717 }
11702 } 11718 }
11703 // Convert to fast double elements if appropriate. 11719 // Convert to fast double elements if appropriate.
11704 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { 11720 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) {
11705 // Consider fixing the boilerplate as well if we have one. 11721 // Consider fixing the boilerplate as well if we have one.
11706 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) 11722 ElementsKind to_kind = IsHoleyElementsKind(elements_kind)
11707 ? FAST_HOLEY_DOUBLE_ELEMENTS 11723 ? FAST_HOLEY_DOUBLE_ELEMENTS
11708 : FAST_DOUBLE_ELEMENTS; 11724 : FAST_DOUBLE_ELEMENTS;
11709 11725
11710 MaybeObject* maybe_failure = UpdateAllocationSiteInfo(to_kind); 11726 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind);
11711 if (maybe_failure->IsFailure()) return maybe_failure; 11727 if (maybe_failure->IsFailure()) return maybe_failure;
11712 11728
11713 MaybeObject* maybe = 11729 MaybeObject* maybe =
11714 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); 11730 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length);
11715 if (maybe->IsFailure()) return maybe; 11731 if (maybe->IsFailure()) return maybe;
11716 FixedDoubleArray::cast(elements())->set(index, value->Number()); 11732 FixedDoubleArray::cast(elements())->set(index, value->Number());
11717 ValidateElements(); 11733 ValidateElements();
11718 return value; 11734 return value;
11719 } 11735 }
11720 // Change elements kind from Smi-only to generic FAST if necessary. 11736 // Change elements kind from Smi-only to generic FAST if necessary.
11721 if (HasFastSmiElements() && !value->IsSmi()) { 11737 if (HasFastSmiElements() && !value->IsSmi()) {
11722 Map* new_map; 11738 Map* new_map;
11723 ElementsKind kind = HasFastHoleyElements() 11739 ElementsKind kind = HasFastHoleyElements()
11724 ? FAST_HOLEY_ELEMENTS 11740 ? FAST_HOLEY_ELEMENTS
11725 : FAST_ELEMENTS; 11741 : FAST_ELEMENTS;
11726 11742
11727 MaybeObject* maybe_failure = UpdateAllocationSiteInfo(kind); 11743 MaybeObject* maybe_failure = UpdateAllocationSite(kind);
11728 if (maybe_failure->IsFailure()) return maybe_failure; 11744 if (maybe_failure->IsFailure()) return maybe_failure;
11729 11745
11730 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), 11746 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(),
11731 kind); 11747 kind);
11732 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 11748 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
11733 11749
11734 set_map(new_map); 11750 set_map(new_map);
11735 } 11751 }
11736 // Increase backing store capacity if that's been decided previously. 11752 // Increase backing store capacity if that's been decided previously.
11737 if (new_capacity != capacity) { 11753 if (new_capacity != capacity) {
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after
12280 12296
12281 12297
12282 Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object, 12298 Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object,
12283 ElementsKind to_kind) { 12299 ElementsKind to_kind) {
12284 CALL_HEAP_FUNCTION(object->GetIsolate(), 12300 CALL_HEAP_FUNCTION(object->GetIsolate(),
12285 object->TransitionElementsKind(to_kind), 12301 object->TransitionElementsKind(to_kind),
12286 Object); 12302 Object);
12287 } 12303 }
12288 12304
12289 12305
12290 MaybeObject* JSObject::UpdateAllocationSiteInfo(ElementsKind to_kind) { 12306 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) {
12291 if (!FLAG_track_allocation_sites || !IsJSArray()) { 12307 if (!FLAG_track_allocation_sites || !IsJSArray()) {
12292 return this; 12308 return this;
12293 } 12309 }
12294 12310
12295 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this); 12311 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this);
12296 if (info == NULL) { 12312 if (info == NULL || !info->IsValid()) {
12297 return this; 12313 return this;
12298 } 12314 }
12299 12315
12300 if (info->payload()->IsJSArray()) { 12316 // Walk through to the Allocation Site
12301 JSArray* payload = JSArray::cast(info->payload()); 12317 AllocationSite* site = info->GetAllocationSite();
12318 if (site->IsLiteralSite()) {
12319 JSArray* payload = JSArray::cast(site->payload());
12302 ElementsKind kind = payload->GetElementsKind(); 12320 ElementsKind kind = payload->GetElementsKind();
12303 if (AllocationSiteInfo::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { 12321 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) {
12304 // If the array is huge, it's not likely to be defined in a local 12322 // If the array is huge, it's not likely to be defined in a local
12305 // function, so we shouldn't make new instances of it very often. 12323 // function, so we shouldn't make new instances of it very often.
12306 uint32_t length = 0; 12324 uint32_t length = 0;
12307 CHECK(payload->length()->ToArrayIndex(&length)); 12325 CHECK(payload->length()->ToArrayIndex(&length));
12308 if (length <= AllocationSiteInfo::kMaximumArrayBytesToPretransition) { 12326 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) {
12309 if (FLAG_trace_track_allocation_sites) { 12327 if (FLAG_trace_track_allocation_sites) {
12310 PrintF( 12328 PrintF(
12311 "AllocationSiteInfo: JSArray %p boilerplate updated %s->%s\n", 12329 "AllocationSite: JSArray %p boilerplate updated %s->%s\n",
12312 reinterpret_cast<void*>(this), 12330 reinterpret_cast<void*>(this),
12313 ElementsKindToString(kind), 12331 ElementsKindToString(kind),
12314 ElementsKindToString(to_kind)); 12332 ElementsKindToString(to_kind));
12315 } 12333 }
12316 return payload->TransitionElementsKind(to_kind); 12334 return payload->TransitionElementsKind(to_kind);
12317 } 12335 }
12318 } 12336 }
12319 } else if (info->payload()->IsCell()) { 12337 } else {
12320 Cell* cell = Cell::cast(info->payload()); 12338 ElementsKind kind = site->GetElementsKindPayload();
12321 Object* cell_contents = cell->value(); 12339 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) {
12322 if (cell_contents->IsSmi()) { 12340 if (FLAG_trace_track_allocation_sites) {
12323 ElementsKind kind = static_cast<ElementsKind>( 12341 PrintF("AllocationSite: JSArray %p site updated %s->%s\n",
12324 Smi::cast(cell_contents)->value()); 12342 reinterpret_cast<void*>(this),
12325 if (AllocationSiteInfo::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { 12343 ElementsKindToString(kind),
12326 if (FLAG_trace_track_allocation_sites) { 12344 ElementsKindToString(to_kind));
12327 PrintF("AllocationSiteInfo: JSArray %p info updated %s->%s\n",
12328 reinterpret_cast<void*>(this),
12329 ElementsKindToString(kind),
12330 ElementsKindToString(to_kind));
12331 }
12332 cell->set_value(Smi::FromInt(to_kind));
12333 } 12345 }
12346 site->set_payload(Smi::FromInt(to_kind));
12334 } 12347 }
12335 } 12348 }
12336 return this; 12349 return this;
12337 } 12350 }
12338 12351
12339 12352
12340 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { 12353 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
12341 ASSERT(!map()->is_observed()); 12354 ASSERT(!map()->is_observed());
12342 ElementsKind from_kind = map()->elements_kind(); 12355 ElementsKind from_kind = map()->elements_kind();
12343 12356
12344 if (IsFastHoleyElementsKind(from_kind)) { 12357 if (IsFastHoleyElementsKind(from_kind)) {
12345 to_kind = GetHoleyElementsKind(to_kind); 12358 to_kind = GetHoleyElementsKind(to_kind);
12346 } 12359 }
12347 12360
12348 if (from_kind == to_kind) return this; 12361 if (from_kind == to_kind) return this;
12349 12362
12350 MaybeObject* maybe_failure = UpdateAllocationSiteInfo(to_kind); 12363 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind);
12351 if (maybe_failure->IsFailure()) return maybe_failure; 12364 if (maybe_failure->IsFailure()) return maybe_failure;
12352 12365
12353 Isolate* isolate = GetIsolate(); 12366 Isolate* isolate = GetIsolate();
12354 if (elements() == isolate->heap()->empty_fixed_array() || 12367 if (elements() == isolate->heap()->empty_fixed_array() ||
12355 (IsFastSmiOrObjectElementsKind(from_kind) && 12368 (IsFastSmiOrObjectElementsKind(from_kind) &&
12356 IsFastSmiOrObjectElementsKind(to_kind)) || 12369 IsFastSmiOrObjectElementsKind(to_kind)) ||
12357 (from_kind == FAST_DOUBLE_ELEMENTS && 12370 (from_kind == FAST_DOUBLE_ELEMENTS &&
12358 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { 12371 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) {
12359 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); 12372 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND);
12360 // No change is needed to the elements() buffer, the transition 12373 // No change is needed to the elements() buffer, the transition
(...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after
13288 } 13301 }
13289 13302
13290 static uint32_t RegExpHash(String* string, Smi* flags) { 13303 static uint32_t RegExpHash(String* string, Smi* flags) {
13291 return string->Hash() + flags->value(); 13304 return string->Hash() + flags->value();
13292 } 13305 }
13293 13306
13294 String* string_; 13307 String* string_;
13295 Smi* flags_; 13308 Smi* flags_;
13296 }; 13309 };
13297 13310
13311
13298 // Utf8StringKey carries a vector of chars as key. 13312 // Utf8StringKey carries a vector of chars as key.
13299 class Utf8StringKey : public HashTableKey { 13313 class Utf8StringKey : public HashTableKey {
13300 public: 13314 public:
13301 explicit Utf8StringKey(Vector<const char> string, uint32_t seed) 13315 explicit Utf8StringKey(Vector<const char> string, uint32_t seed)
13302 : string_(string), hash_field_(0), seed_(seed) { } 13316 : string_(string), hash_field_(0), seed_(seed) { }
13303 13317
13304 bool IsMatch(Object* string) { 13318 bool IsMatch(Object* string) {
13305 return String::cast(string)->IsUtf8EqualTo(string_); 13319 return String::cast(string)->IsUtf8EqualTo(string_);
13306 } 13320 }
13307 13321
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
13654 uint32_t count = 1; 13668 uint32_t count = 1;
13655 // EnsureCapacity will guarantee the hash table is never full. 13669 // EnsureCapacity will guarantee the hash table is never full.
13656 while (true) { 13670 while (true) {
13657 Object* element = KeyAt(entry); 13671 Object* element = KeyAt(entry);
13658 if (element->IsUndefined() || element->IsTheHole()) break; 13672 if (element->IsUndefined() || element->IsTheHole()) break;
13659 entry = NextProbe(entry, count++, capacity); 13673 entry = NextProbe(entry, count++, capacity);
13660 } 13674 }
13661 return entry; 13675 return entry;
13662 } 13676 }
13663 13677
13678
13664 // Force instantiation of template instances class. 13679 // Force instantiation of template instances class.
13665 // Please note this list is compiler dependent. 13680 // Please note this list is compiler dependent.
13666 13681
13667 template class HashTable<StringTableShape, HashTableKey*>; 13682 template class HashTable<StringTableShape, HashTableKey*>;
13668 13683
13669 template class HashTable<CompilationCacheShape, HashTableKey*>; 13684 template class HashTable<CompilationCacheShape, HashTableKey*>;
13670 13685
13671 template class HashTable<MapCacheShape, HashTableKey*>; 13686 template class HashTable<MapCacheShape, HashTableKey*>;
13672 13687
13673 template class HashTable<ObjectHashTableShape<1>, Object*>; 13688 template class HashTable<ObjectHashTableShape<1>, Object*>;
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
14016 } 14031 }
14017 14032
14018 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { 14033 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) {
14019 return Smi::FromInt(static_cast<int>(result)); 14034 return Smi::FromInt(static_cast<int>(result));
14020 } 14035 }
14021 ASSERT_NE(NULL, result_double); 14036 ASSERT_NE(NULL, result_double);
14022 result_double->set_value(static_cast<double>(result)); 14037 result_double->set_value(static_cast<double>(result));
14023 return result_double; 14038 return result_double;
14024 } 14039 }
14025 14040
14041
14026 ExternalArrayType JSTypedArray::type() { 14042 ExternalArrayType JSTypedArray::type() {
14027 switch (elements()->map()->instance_type()) { 14043 switch (elements()->map()->instance_type()) {
14028 case EXTERNAL_BYTE_ARRAY_TYPE: 14044 case EXTERNAL_BYTE_ARRAY_TYPE:
14029 return kExternalByteArray; 14045 return kExternalByteArray;
14030 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 14046 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
14031 return kExternalUnsignedByteArray; 14047 return kExternalUnsignedByteArray;
14032 case EXTERNAL_SHORT_ARRAY_TYPE: 14048 case EXTERNAL_SHORT_ARRAY_TYPE:
14033 return kExternalShortArray; 14049 return kExternalShortArray;
14034 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: 14050 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
14035 return kExternalUnsignedShortArray; 14051 return kExternalUnsignedShortArray;
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
14230 } 14246 }
14231 14247
14232 14248
14233 PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { 14249 PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) {
14234 ASSERT(!HasFastProperties()); 14250 ASSERT(!HasFastProperties());
14235 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 14251 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
14236 return PropertyCell::cast(value); 14252 return PropertyCell::cast(value);
14237 } 14253 }
14238 14254
14239 14255
14256 // TODO(mstarzinger): Temporary wrapper until handlified.
14257 static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
14258 Handle<Name> name,
14259 Handle<Object> value,
14260 PropertyDetails details) {
14261 CALL_HEAP_FUNCTION(dict->GetIsolate(),
14262 dict->Add(*name, *value, details),
14263 NameDictionary);
14264 }
14265
14266
14240 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( 14267 Handle<PropertyCell> GlobalObject::EnsurePropertyCell(
14241 Handle<GlobalObject> global, 14268 Handle<GlobalObject> global,
14242 Handle<Name> name) { 14269 Handle<Name> name) {
14243 Isolate* isolate = global->GetIsolate(); 14270 ASSERT(!global->HasFastProperties());
14244 CALL_HEAP_FUNCTION(isolate, 14271 int entry = global->property_dictionary()->FindEntry(*name);
14245 global->EnsurePropertyCell(*name),
14246 PropertyCell);
14247 }
14248
14249
14250 MaybeObject* GlobalObject::EnsurePropertyCell(Name* name) {
14251 ASSERT(!HasFastProperties());
14252 int entry = property_dictionary()->FindEntry(name);
14253 if (entry == NameDictionary::kNotFound) { 14272 if (entry == NameDictionary::kNotFound) {
14254 Heap* heap = GetHeap(); 14273 Isolate* isolate = global->GetIsolate();
14255 Object* cell; 14274 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(
14256 { MaybeObject* maybe_cell = 14275 isolate->factory()->the_hole_value());
14257 heap->AllocatePropertyCell(heap->the_hole_value());
14258 if (!maybe_cell->ToObject(&cell)) return maybe_cell;
14259 }
14260 PropertyDetails details(NONE, NORMAL, 0); 14276 PropertyDetails details(NONE, NORMAL, 0);
14261 details = details.AsDeleted(); 14277 details = details.AsDeleted();
14262 Object* dictionary; 14278 Handle<NameDictionary> dictionary = NameDictionaryAdd(
14263 { MaybeObject* maybe_dictionary = 14279 handle(global->property_dictionary()), name, cell, details);
14264 property_dictionary()->Add(name, cell, details); 14280 global->set_properties(*dictionary);
14265 if (!maybe_dictionary->ToObject(&dictionary)) return maybe_dictionary;
14266 }
14267 set_properties(NameDictionary::cast(dictionary));
14268 return cell; 14281 return cell;
14269 } else { 14282 } else {
14270 Object* value = property_dictionary()->ValueAt(entry); 14283 Object* value = global->property_dictionary()->ValueAt(entry);
14271 ASSERT(value->IsPropertyCell()); 14284 ASSERT(value->IsPropertyCell());
14272 return value; 14285 return handle(PropertyCell::cast(value));
14273 } 14286 }
14274 } 14287 }
14275 14288
14276 14289
14277 MaybeObject* StringTable::LookupString(String* string, Object** s) { 14290 MaybeObject* StringTable::LookupString(String* string, Object** s) {
14278 InternalizedStringKey key(string); 14291 InternalizedStringKey key(string);
14279 return LookupKey(&key, s); 14292 return LookupKey(&key, s);
14280 } 14293 }
14281 14294
14282 14295
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
14395 return LookupKey(&key, s); 14408 return LookupKey(&key, s);
14396 } 14409 }
14397 14410
14398 14411
14399 MaybeObject* StringTable::LookupTwoByteString(Vector<const uc16> str, 14412 MaybeObject* StringTable::LookupTwoByteString(Vector<const uc16> str,
14400 Object** s) { 14413 Object** s) {
14401 TwoByteStringKey key(str, GetHeap()->HashSeed()); 14414 TwoByteStringKey key(str, GetHeap()->HashSeed());
14402 return LookupKey(&key, s); 14415 return LookupKey(&key, s);
14403 } 14416 }
14404 14417
14418
14405 MaybeObject* StringTable::LookupKey(HashTableKey* key, Object** s) { 14419 MaybeObject* StringTable::LookupKey(HashTableKey* key, Object** s) {
14406 int entry = FindEntry(key); 14420 int entry = FindEntry(key);
14407 14421
14408 // String already in table. 14422 // String already in table.
14409 if (entry != kNotFound) { 14423 if (entry != kNotFound) {
14410 *s = KeyAt(entry); 14424 *s = KeyAt(entry);
14411 return this; 14425 return this;
14412 } 14426 }
14413 14427
14414 // Adding new string. Grow table if needed. 14428 // Adding new string. Grow table if needed.
(...skipping 1376 matching lines...) Expand 10 before | Expand all | Expand 10 after
15791 set_elements(GetHeap()->EmptyExternalArrayForMap(map())); 15805 set_elements(GetHeap()->EmptyExternalArrayForMap(map()));
15792 } 15806 }
15793 15807
15794 15808
15795 Type* PropertyCell::type() { 15809 Type* PropertyCell::type() {
15796 return static_cast<Type*>(type_raw()); 15810 return static_cast<Type*>(type_raw());
15797 } 15811 }
15798 15812
15799 15813
15800 void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) { 15814 void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) {
15815 ASSERT(IsPropertyCell());
15801 set_type_raw(type, ignored); 15816 set_type_raw(type, ignored);
15802 } 15817 }
15803 15818
15804 15819
15820 Type* PropertyCell::UpdateType(Handle<PropertyCell> cell,
15821 Handle<Object> value) {
15822 Isolate* isolate = cell->GetIsolate();
15823 Handle<Type> old_type(cell->type(), isolate);
15824 Handle<Type> new_type((value->IsSmi() || value->IsJSFunction() ||
15825 value->IsUndefined())
15826 ? Type::Constant(value, isolate)
15827 : Type::Any(), isolate);
15828
15829 if (new_type->Is(old_type)) {
15830 return *old_type;
15831 }
15832
15833 cell->dependent_code()->DeoptimizeDependentCodeGroup(
15834 isolate, DependentCode::kPropertyCellChangedGroup);
15835
15836 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) {
15837 return *new_type;
15838 }
15839
15840 return Type::Any();
15841 }
15842
15843
15844 MaybeObject* PropertyCell::SetValueInferType(Object* value,
15845 WriteBarrierMode ignored) {
15846 set_value(value, ignored);
15847 if (!Type::Any()->Is(type())) {
15848 IdempotentPointerToHandleCodeTrampoline trampoline(GetIsolate());
15849 MaybeObject* maybe_type = trampoline.CallWithReturnValue(
15850 &PropertyCell::UpdateType,
15851 Handle<PropertyCell>(this),
15852 Handle<Object>(value, GetIsolate()));
15853 if (maybe_type->IsFailure()) return maybe_type;
15854 Type* new_type = static_cast<Type*>(maybe_type);
15855 set_type(new_type);
15856 }
15857 return value;
15858 }
15859
15860
15805 void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) { 15861 void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) {
15806 Handle<DependentCode> dep(dependent_code()); 15862 Handle<DependentCode> dep(dependent_code());
15807 Handle<DependentCode> codes = 15863 Handle<DependentCode> codes =
15808 DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup, 15864 DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup,
15809 info->object_wrapper()); 15865 info->object_wrapper());
15810 if (*codes != dependent_code()) set_dependent_code(*codes); 15866 if (*codes != dependent_code()) set_dependent_code(*codes);
15811 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 15867 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
15812 Handle<HeapObject>(this), info->zone()); 15868 Handle<HeapObject>(this), info->zone());
15813 } 15869 }
15814 15870
15815 15871
15816 void PropertyCell::AddDependentCode(Handle<Code> code) { 15872 void PropertyCell::AddDependentCode(Handle<Code> code) {
15817 Handle<DependentCode> codes = DependentCode::Insert( 15873 Handle<DependentCode> codes = DependentCode::Insert(
15818 Handle<DependentCode>(dependent_code()), 15874 Handle<DependentCode>(dependent_code()),
15819 DependentCode::kPropertyCellChangedGroup, code); 15875 DependentCode::kPropertyCellChangedGroup, code);
15820 if (*codes != dependent_code()) set_dependent_code(*codes); 15876 if (*codes != dependent_code()) set_dependent_code(*codes);
15821 } 15877 }
15822 15878
15823 15879
15824 } } // namespace v8::internal 15880 } } // 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