OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 Code); | 885 Code); |
886 } | 886 } |
887 | 887 |
888 | 888 |
889 Handle<String> Factory::SymbolFromString(Handle<String> value) { | 889 Handle<String> Factory::SymbolFromString(Handle<String> value) { |
890 CALL_HEAP_FUNCTION(isolate(), | 890 CALL_HEAP_FUNCTION(isolate(), |
891 isolate()->heap()->LookupSymbol(*value), String); | 891 isolate()->heap()->LookupSymbol(*value), String); |
892 } | 892 } |
893 | 893 |
894 | 894 |
895 Handle<DescriptorArray> Factory::CopyAppendCallbackDescriptors( | 895 void Factory::CopyAppendCallbackDescriptors(Handle<Map> map, |
896 Handle<DescriptorArray> array, | 896 Handle<Object> descriptors) { |
897 Handle<Object> descriptors) { | 897 Handle<DescriptorArray> array(map->instance_descriptors()); |
898 v8::NeanderArray callbacks(descriptors); | 898 v8::NeanderArray callbacks(descriptors); |
899 int nof_callbacks = callbacks.length(); | 899 int nof_callbacks = callbacks.length(); |
900 int descriptor_count = array->number_of_descriptors(); | 900 int descriptor_count = array->number_of_descriptors(); |
901 Handle<DescriptorArray> result = | 901 Handle<DescriptorArray> result = |
902 NewDescriptorArray(descriptor_count + nof_callbacks); | 902 NewDescriptorArray(descriptor_count + nof_callbacks); |
903 | 903 |
904 // Ensure that marking will not progress and change color of objects. | 904 // Ensure that marking will not progress and change color of objects. |
905 DescriptorArray::WhitenessWitness witness(*result); | 905 DescriptorArray::WhitenessWitness witness(*result); |
906 | 906 |
907 // Copy the descriptors from the array. | 907 // Copy the descriptors from the array. |
908 if (0 < descriptor_count) { | 908 if (0 < descriptor_count) { |
909 result->SetLastAdded(array->LastAdded()); | 909 result->SetLastAdded(array->LastAdded()); |
910 for (int i = 0; i < descriptor_count; i++) { | 910 for (int i = 0; i < descriptor_count; i++) { |
911 result->CopyFrom(i, *array, i, witness); | 911 result->CopyFrom(i, *array, i, witness); |
912 } | 912 } |
913 } | 913 } |
914 | 914 |
915 // Fill in new callback descriptors. Process the callbacks from | 915 // Fill in new callback descriptors. Process the callbacks from |
916 // back to front so that the last callback with a given name takes | 916 // back to front so that the last callback with a given name takes |
917 // precedence over previously added callbacks with that name. | 917 // precedence over previously added callbacks with that name. |
918 for (int i = nof_callbacks - 1; i >= 0; i--) { | 918 for (int i = nof_callbacks - 1; i >= 0; i--) { |
919 Handle<AccessorInfo> entry = | 919 Handle<AccessorInfo> entry = |
920 Handle<AccessorInfo>(AccessorInfo::cast(callbacks.get(i))); | 920 Handle<AccessorInfo>(AccessorInfo::cast(callbacks.get(i))); |
921 // Ensure the key is a symbol before writing into the instance descriptor. | 921 // Ensure the key is a symbol before writing into the instance descriptor. |
922 Handle<String> key = | 922 Handle<String> key = |
923 SymbolFromString(Handle<String>(String::cast(entry->name()))); | 923 SymbolFromString(Handle<String>(String::cast(entry->name()))); |
924 // Check if a descriptor with this name already exists before writing. | 924 // Check if a descriptor with this name already exists before writing. |
925 if (LinearSearch(*result, | 925 if (LinearSearch(*result, *key, result->NumberOfSetDescriptors()) == |
926 EXPECT_UNSORTED, | |
927 *key, | |
928 result->NumberOfSetDescriptors()) == | |
929 DescriptorArray::kNotFound) { | 926 DescriptorArray::kNotFound) { |
930 CallbacksDescriptor desc(*key, *entry, entry->property_attributes()); | 927 CallbacksDescriptor desc(*key, *entry, entry->property_attributes()); |
931 result->Append(&desc, witness); | 928 result->Append(&desc, witness); |
932 } | 929 } |
933 } | 930 } |
934 | 931 |
935 int new_number_of_descriptors = result->NumberOfSetDescriptors(); | 932 int new_number_of_descriptors = result->NumberOfSetDescriptors(); |
936 // Return the old descriptor array if there were no new elements. | 933 // Don't replace the descriptor array if there were no new elements. |
937 if (new_number_of_descriptors == descriptor_count) return array; | 934 if (new_number_of_descriptors == descriptor_count) return; |
938 | 935 |
939 // If duplicates were detected, allocate a result of the right size | 936 // If duplicates were detected, allocate a result of the right size |
940 // and transfer the elements. | 937 // and transfer the elements. |
941 if (new_number_of_descriptors < result->length()) { | 938 if (new_number_of_descriptors < result->length()) { |
942 Handle<DescriptorArray> new_result = | 939 Handle<DescriptorArray> new_result = |
943 NewDescriptorArray(new_number_of_descriptors); | 940 NewDescriptorArray(new_number_of_descriptors); |
944 for (int i = 0; i < new_number_of_descriptors; i++) { | 941 for (int i = 0; i < new_number_of_descriptors; i++) { |
945 new_result->CopyFrom(i, *result, i, witness); | 942 new_result->CopyFrom(i, *result, i, witness); |
946 } | 943 } |
| 944 new_result->SetLastAdded(result->LastAdded()); |
947 result = new_result; | 945 result = new_result; |
948 } | 946 } |
949 | 947 |
950 // Sort the result before returning. | 948 map->set_instance_descriptors(*result); |
951 result->Sort(witness); | |
952 return result; | |
953 } | 949 } |
954 | 950 |
955 | 951 |
956 Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor, | 952 Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor, |
957 PretenureFlag pretenure) { | 953 PretenureFlag pretenure) { |
958 CALL_HEAP_FUNCTION( | 954 CALL_HEAP_FUNCTION( |
959 isolate(), | 955 isolate(), |
960 isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject); | 956 isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject); |
961 } | 957 } |
962 | 958 |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1330 // Set instance call-as-function information in the map. | 1326 // Set instance call-as-function information in the map. |
1331 if (!obj->instance_call_handler()->IsUndefined()) { | 1327 if (!obj->instance_call_handler()->IsUndefined()) { |
1332 map->set_has_instance_call_handler(); | 1328 map->set_has_instance_call_handler(); |
1333 } | 1329 } |
1334 | 1330 |
1335 result->shared()->set_function_data(*obj); | 1331 result->shared()->set_function_data(*obj); |
1336 result->shared()->set_construct_stub(*construct_stub); | 1332 result->shared()->set_construct_stub(*construct_stub); |
1337 result->shared()->DontAdaptArguments(); | 1333 result->shared()->DontAdaptArguments(); |
1338 | 1334 |
1339 // Recursively copy parent templates' accessors, 'data' may be modified. | 1335 // Recursively copy parent templates' accessors, 'data' may be modified. |
1340 Handle<DescriptorArray> array = | |
1341 Handle<DescriptorArray>(map->instance_descriptors()); | |
1342 while (true) { | 1336 while (true) { |
1343 Handle<Object> props = Handle<Object>(obj->property_accessors()); | 1337 Handle<Object> props = Handle<Object>(obj->property_accessors()); |
1344 if (!props->IsUndefined()) { | 1338 if (!props->IsUndefined()) { |
1345 array = CopyAppendCallbackDescriptors(array, props); | 1339 CopyAppendCallbackDescriptors(map, props); |
1346 } | 1340 } |
1347 Handle<Object> parent = Handle<Object>(obj->parent_template()); | 1341 Handle<Object> parent = Handle<Object>(obj->parent_template()); |
1348 if (parent->IsUndefined()) break; | 1342 if (parent->IsUndefined()) break; |
1349 obj = Handle<FunctionTemplateInfo>::cast(parent); | 1343 obj = Handle<FunctionTemplateInfo>::cast(parent); |
1350 } | 1344 } |
1351 if (!array->IsEmpty()) { | |
1352 map->set_instance_descriptors(*array); | |
1353 } | |
1354 | 1345 |
1355 ASSERT(result->shared()->IsApiFunction()); | 1346 ASSERT(result->shared()->IsApiFunction()); |
1356 return result; | 1347 return result; |
1357 } | 1348 } |
1358 | 1349 |
1359 | 1350 |
1360 Handle<MapCache> Factory::NewMapCache(int at_least_space_for) { | 1351 Handle<MapCache> Factory::NewMapCache(int at_least_space_for) { |
1361 CALL_HEAP_FUNCTION(isolate(), | 1352 CALL_HEAP_FUNCTION(isolate(), |
1362 MapCache::Allocate(at_least_space_for), MapCache); | 1353 MapCache::Allocate(at_least_space_for), MapCache); |
1363 } | 1354 } |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 | 1458 |
1468 | 1459 |
1469 Handle<Object> Factory::ToBoolean(bool value) { | 1460 Handle<Object> Factory::ToBoolean(bool value) { |
1470 return Handle<Object>(value | 1461 return Handle<Object>(value |
1471 ? isolate()->heap()->true_value() | 1462 ? isolate()->heap()->true_value() |
1472 : isolate()->heap()->false_value()); | 1463 : isolate()->heap()->false_value()); |
1473 } | 1464 } |
1474 | 1465 |
1475 | 1466 |
1476 } } // namespace v8::internal | 1467 } } // namespace v8::internal |
OLD | NEW |