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 9677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9688 int result = SeededNumberDictionary::cast(elements)->NumberOfElements(); | 9688 int result = SeededNumberDictionary::cast(elements)->NumberOfElements(); |
9689 return Smi::FromInt(result); | 9689 return Smi::FromInt(result); |
9690 } else if (object->IsJSArray()) { | 9690 } else if (object->IsJSArray()) { |
9691 return JSArray::cast(object)->length(); | 9691 return JSArray::cast(object)->length(); |
9692 } else { | 9692 } else { |
9693 return Smi::FromInt(FixedArray::cast(elements)->length()); | 9693 return Smi::FromInt(FixedArray::cast(elements)->length()); |
9694 } | 9694 } |
9695 } | 9695 } |
9696 | 9696 |
9697 | 9697 |
9698 static Handle<Object> NewSingleInterval(Isolate* isolate, uint32_t length) { | |
9699 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); | |
9700 // -1 means start of array. | |
9701 single_interval->set(0, Smi::FromInt(-1)); | |
9702 Handle<Object> number = isolate->factory()->NewNumberFromUint(length); | |
9703 single_interval->set(1, *number); | |
9704 return isolate->factory()->NewJSArrayWithElements(single_interval); | |
9705 } | |
9706 | |
9707 | |
9708 // Returns an array that tells you where in the [0, length) interval an array | 9698 // Returns an array that tells you where in the [0, length) interval an array |
9709 // might have elements. Can either return keys (positive integers) or | 9699 // might have elements. Can either return an array of keys (positive integers |
9710 // intervals (pair of a negative integer (-start-1) followed by a | 9700 // or undefined) or a number representing the positive length of an interval |
9711 // positive (length)) or undefined values. | 9701 // starting at index 0. |
9712 // Intervals can span over some keys that are not in the object. | 9702 // Intervals can span over some keys that are not in the object. |
9713 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { | 9703 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { |
9714 HandleScope scope(isolate); | 9704 HandleScope scope(isolate); |
9715 ASSERT(args.length() == 2); | 9705 ASSERT(args.length() == 2); |
9716 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); | 9706 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); |
9717 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 9707 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
9718 if (array->elements()->IsDictionary()) { | 9708 if (array->elements()->IsDictionary()) { |
9719 Handle<FixedArray> keys = isolate->factory()->empty_fixed_array(); | 9709 Handle<FixedArray> keys = isolate->factory()->empty_fixed_array(); |
9720 for (Handle<Object> p = array; | 9710 for (Handle<Object> p = array; |
9721 !p->IsNull(); | 9711 !p->IsNull(); |
9722 p = Handle<Object>(p->GetPrototype(isolate), isolate)) { | 9712 p = Handle<Object>(p->GetPrototype(isolate), isolate)) { |
9723 if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) { | 9713 if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) { |
9724 // Bail out if we find a proxy or interceptor, likely not worth | 9714 // Bail out if we find a proxy or interceptor, likely not worth |
9725 // collecting keys in that case. | 9715 // collecting keys in that case. |
9726 return *NewSingleInterval(isolate, length); | 9716 return *isolate->factory()->NewNumberFromUint(length); |
9727 } | 9717 } |
9728 Handle<JSObject> current = Handle<JSObject>::cast(p); | 9718 Handle<JSObject> current = Handle<JSObject>::cast(p); |
9729 Handle<FixedArray> current_keys = | 9719 Handle<FixedArray> current_keys = |
9730 isolate->factory()->NewFixedArray( | 9720 isolate->factory()->NewFixedArray( |
9731 current->NumberOfLocalElements(NONE)); | 9721 current->NumberOfLocalElements(NONE)); |
9732 current->GetLocalElementKeys(*current_keys, NONE); | 9722 current->GetLocalElementKeys(*current_keys, NONE); |
9733 keys = UnionOfKeys(keys, current_keys); | 9723 keys = UnionOfKeys(keys, current_keys); |
9734 } | 9724 } |
9735 // Erase any keys >= length. | 9725 // Erase any keys >= length. |
9736 // TODO(adamk): Remove this step when the contract of %GetArrayKeys | 9726 // TODO(adamk): Remove this step when the contract of %GetArrayKeys |
9737 // is changed to let this happen on the JS side. | 9727 // is changed to let this happen on the JS side. |
9738 for (int i = 0; i < keys->length(); i++) { | 9728 for (int i = 0; i < keys->length(); i++) { |
9739 if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i); | 9729 if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i); |
9740 } | 9730 } |
9741 return *isolate->factory()->NewJSArrayWithElements(keys); | 9731 return *isolate->factory()->NewJSArrayWithElements(keys); |
9742 } else { | 9732 } else { |
9743 ASSERT(array->HasFastSmiOrObjectElements() || | 9733 ASSERT(array->HasFastSmiOrObjectElements() || |
9744 array->HasFastDoubleElements()); | 9734 array->HasFastDoubleElements()); |
9745 uint32_t actual_length = static_cast<uint32_t>(array->elements()->length()); | 9735 uint32_t actual_length = static_cast<uint32_t>(array->elements()->length()); |
9746 return *NewSingleInterval(isolate, Min(actual_length, length)); | 9736 return *isolate->factory()->NewNumberFromUint(Min(actual_length, length)); |
9747 } | 9737 } |
9748 } | 9738 } |
9749 | 9739 |
9750 | 9740 |
9751 RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) { | 9741 RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) { |
9752 NoHandleAllocation ha(isolate); | 9742 NoHandleAllocation ha(isolate); |
9753 ASSERT(args.length() == 3); | 9743 ASSERT(args.length() == 3); |
9754 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 9744 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
9755 CONVERT_ARG_CHECKED(Name, name, 1); | 9745 CONVERT_ARG_CHECKED(Name, name, 1); |
9756 CONVERT_SMI_ARG_CHECKED(flag, 2); | 9746 CONVERT_SMI_ARG_CHECKED(flag, 2); |
(...skipping 3393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13150 // Handle last resort GC and make sure to allow future allocations | 13140 // Handle last resort GC and make sure to allow future allocations |
13151 // to grow the heap without causing GCs (if possible). | 13141 // to grow the heap without causing GCs (if possible). |
13152 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13142 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13153 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13143 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13154 "Runtime::PerformGC"); | 13144 "Runtime::PerformGC"); |
13155 } | 13145 } |
13156 } | 13146 } |
13157 | 13147 |
13158 | 13148 |
13159 } } // namespace v8::internal | 13149 } } // namespace v8::internal |
OLD | NEW |