diff --git a/src/arm/interface-descriptors-arm.cc b/src/arm/interface-descriptors-arm.cc index 78febc3fd8..6e77ee474a 100644 --- a/src/arm/interface-descriptors-arm.cc +++ b/src/arm/interface-descriptors-arm.cc @@ -54,12 +54,6 @@ const Register MathPowIntegerDescriptor::exponent() { } -// IC register specifications -const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; } -const Register GrowArrayElementsDescriptor::KeyRegister() { return r1; } -const Register GrowArrayElementsDescriptor::CapacityRegister() { return r2; } - - void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) { Register registers[] = {cp, r2}; data->Initialize(arraysize(registers), registers, NULL); diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index bb81960dec..e323e0d210 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -4015,12 +4015,8 @@ void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); PlatformInterfaceDescriptor* call_descriptor = instr->descriptor().platform_specific_descriptor(); - if (call_descriptor != NULL) { - __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None(), al, - call_descriptor->storage_mode()); - } else { - __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None(), al); - } + __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None(), al, + call_descriptor->storage_mode()); } else { DCHECK(instr->target()->IsRegister()); Register target = ToRegister(instr->target()); diff --git a/src/arm64/interface-descriptors-arm64.cc b/src/arm64/interface-descriptors-arm64.cc index f7e6c5f6d4..57eebcc3b5 100644 --- a/src/arm64/interface-descriptors-arm64.cc +++ b/src/arm64/interface-descriptors-arm64.cc @@ -60,12 +60,6 @@ const Register MathPowTaggedDescriptor::exponent() { return x11; } const Register MathPowIntegerDescriptor::exponent() { return x12; } -// IC register specifications -const Register GrowArrayElementsDescriptor::ObjectRegister() { return x0; } -const Register GrowArrayElementsDescriptor::KeyRegister() { return x1; } -const Register GrowArrayElementsDescriptor::CapacityRegister() { return x2; } - - void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) { // cp: context // x2: function info diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index a9cd5b4691..f66670bfe9 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -547,31 +547,6 @@ Handle StoreScriptContextFieldStub::GenerateCode() { } -template <> -HValue* CodeStubGraphBuilder::BuildCodeStub() { - HValue* object = GetParameter(GrowArrayElementsDescriptor::kObjectIndex); - HValue* key = GetParameter(GrowArrayElementsDescriptor::kKeyIndex); - HValue* current_capacity = - GetParameter(GrowArrayElementsDescriptor::kCapacityIndex); - ElementsKind kind = casted_stub()->elements_kind(); - - HValue* elements = AddLoadElements(object); - HValue* length = - casted_stub()->is_js_array() - ? Add(object, static_cast(NULL), - HObjectAccess::ForArrayLength(kind)) - : current_capacity; - - return BuildCheckAndGrowElementsCapacity(object, elements, kind, length, - current_capacity, key); -} - - -Handle GrowArrayElementsStub::GenerateCode() { - return DoGenerateCode(this); -} - - template <> HValue* CodeStubGraphBuilder::BuildCodeStub() { HInstruction* load = BuildUncheckedMonomorphicElementAccess( diff --git a/src/code-stubs.cc b/src/code-stubs.cc index 6b69832586..7442f3e134 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -733,13 +733,6 @@ void StringAddStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { } -void GrowArrayElementsStub::InitializeDescriptor( - CodeStubDescriptor* descriptor) { - descriptor->Initialize( - Runtime::FunctionForId(Runtime::kGrowArrayElements)->entry); -} - - void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) { CreateAllocationSiteStub stub(isolate); stub.GetCode(); diff --git a/src/code-stubs.h b/src/code-stubs.h index bf87a0d157..7a6ad6ad6e 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -65,7 +65,6 @@ namespace internal { V(FastCloneShallowObject) \ V(FastNewClosure) \ V(FastNewContext) \ - V(GrowArrayElements) \ V(InternalArrayNArgumentsConstructor) \ V(InternalArrayNoArgumentConstructor) \ V(InternalArraySingleArgumentConstructor) \ @@ -663,29 +662,6 @@ class CreateAllocationSiteStub : public HydrogenCodeStub { }; -class GrowArrayElementsStub : public HydrogenCodeStub { - public: - GrowArrayElementsStub(Isolate* isolate, bool is_js_array, ElementsKind kind) - : HydrogenCodeStub(isolate) { - set_sub_minor_key(ElementsKindBits::encode(kind) | - IsJsArrayBits::encode(is_js_array)); - } - - ElementsKind elements_kind() const { - return ElementsKindBits::decode(sub_minor_key()); - } - - bool is_js_array() const { return IsJsArrayBits::decode(sub_minor_key()); } - - private: - class ElementsKindBits : public BitField {}; - class IsJsArrayBits : public BitField {}; - - DEFINE_CALL_INTERFACE_DESCRIPTOR(GrowArrayElements); - DEFINE_HYDROGEN_CODE_STUB(GrowArrayElements, HydrogenCodeStub); -}; - - class InstanceofStub: public PlatformCodeStub { public: enum Flags { diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 0f28c31e39..bc7b2ce3b5 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -783,9 +783,6 @@ void HInstruction::Verify() { bool HInstruction::CanDeoptimize() { // TODO(titzer): make this a virtual method? - // TODO(all): Some of these may be incorrect, since any method that can - // collect can provoke lazy deoptimization. Methods like CallNew can - // certainly do that. switch (opcode()) { case HValue::kAbnormalExit: case HValue::kAccessArgumentsAt: @@ -799,6 +796,7 @@ bool HInstruction::CanDeoptimize() { case HValue::kCallNew: case HValue::kCallNewArray: case HValue::kCallStub: + case HValue::kCallWithDescriptor: case HValue::kCapturedObject: case HValue::kClassOfTestAndBranch: case HValue::kCompareGeneric: @@ -865,7 +863,6 @@ bool HInstruction::CanDeoptimize() { case HValue::kBranch: case HValue::kCallJSFunction: case HValue::kCallRuntime: - case HValue::kCallWithDescriptor: case HValue::kChange: case HValue::kCheckHeapObject: case HValue::kCheckInstanceType: diff --git a/src/hydrogen.cc b/src/hydrogen.cc index d188cb886f..21ef8c019f 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -1297,20 +1297,6 @@ HValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) { } -HValue* HGraphBuilder::BuildCheckAndGrowElementsCapacity( - HValue* object, HValue* elements, ElementsKind kind, HValue* length, - HValue* capacity, HValue* key) { - HValue* max_gap = Add(static_cast(JSObject::kMaxGap)); - HValue* max_capacity = AddUncasted(capacity, max_gap); - Add(key, max_capacity); - - HValue* new_capacity = BuildNewElementsCapacity(key); - HValue* new_elements = BuildGrowElementsCapacity(object, elements, kind, kind, - length, new_capacity); - return new_elements; -} - - HValue* HGraphBuilder::BuildCheckForCapacityGrow( HValue* object, HValue* elements, @@ -1334,26 +1320,17 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow( Token::GTE); capacity_checker.Then(); - // BuildCheckAndGrowElementsCapacity could de-opt without profitable feedback, - // therefore we defer calling it to a stub in optimized functions. It is - // okay to call directly in a code stub though, because a bailout to the - // runtime is tolerable in the corner cases. - if (top_info()->IsStub()) { - environment()->Push(BuildCheckAndGrowElementsCapacity( - object, elements, kind, length, current_capacity, key)); - } else { - GrowArrayElementsStub stub(isolate(), is_js_array, kind); - GrowArrayElementsDescriptor descriptor(isolate()); - HConstant* target = Add(stub.GetCode()); - HValue* op_vals[] = {context(), object, key, current_capacity}; - HValue* new_elements = Add( - target, 0, descriptor, Vector(op_vals, 4)); - // If the object changed to a dictionary, GrowArrayElements will return a - // smi to signal that deopt is required. - Add(new_elements); - environment()->Push(new_elements); - } + HValue* max_gap = Add(static_cast(JSObject::kMaxGap)); + HValue* max_capacity = AddUncasted(current_capacity, max_gap); + Add(key, max_capacity); + + HValue* new_capacity = BuildNewElementsCapacity(key); + HValue* new_elements = BuildGrowElementsCapacity(object, elements, + kind, kind, length, + new_capacity); + + environment()->Push(new_elements); capacity_checker.Else(); environment()->Push(elements); diff --git a/src/hydrogen.h b/src/hydrogen.h index 43388464cb..773ea8a3f4 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -1335,10 +1335,6 @@ class HGraphBuilder { bool is_js_array, PropertyAccessType access_type); - HValue* BuildCheckAndGrowElementsCapacity(HValue* object, HValue* elements, - ElementsKind kind, HValue* length, - HValue* capacity, HValue* key); - HValue* BuildCopyElementsOnWrite(HValue* object, HValue* elements, ElementsKind kind, diff --git a/src/ia32/interface-descriptors-ia32.cc b/src/ia32/interface-descriptors-ia32.cc index 9404340b19..6c77ef8f81 100644 --- a/src/ia32/interface-descriptors-ia32.cc +++ b/src/ia32/interface-descriptors-ia32.cc @@ -56,11 +56,6 @@ const Register MathPowIntegerDescriptor::exponent() { } -const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; } -const Register GrowArrayElementsDescriptor::KeyRegister() { return ebx; } -const Register GrowArrayElementsDescriptor::CapacityRegister() { return ecx; } - - void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) { Register registers[] = {esi, ebx}; data->Initialize(arraysize(registers), registers, NULL); diff --git a/src/interface-descriptors.cc b/src/interface-descriptors.cc index 4c7a1159b5..b1ebc3faee 100644 --- a/src/interface-descriptors.cc +++ b/src/interface-descriptors.cc @@ -146,12 +146,5 @@ void ContextOnlyDescriptor::Initialize(CallInterfaceDescriptorData* data) { data->Initialize(arraysize(registers), registers, NULL); } - -void GrowArrayElementsDescriptor::Initialize( - CallInterfaceDescriptorData* data) { - Register registers[] = {ContextRegister(), ObjectRegister(), KeyRegister(), - CapacityRegister()}; - data->Initialize(arraysize(registers), registers, NULL); -} } } // namespace v8::internal diff --git a/src/interface-descriptors.h b/src/interface-descriptors.h index 4ececd7b21..5d02e84ebd 100644 --- a/src/interface-descriptors.h +++ b/src/interface-descriptors.h @@ -53,8 +53,7 @@ class PlatformInterfaceDescriptor; V(StoreArrayLiteralElement) \ V(MathPowTagged) \ V(MathPowInteger) \ - V(ContextOnly) \ - V(GrowArrayElements) + V(ContextOnly) class CallInterfaceDescriptorData { @@ -489,17 +488,6 @@ class ContextOnlyDescriptor : public CallInterfaceDescriptor { DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor) }; - -class GrowArrayElementsDescriptor : public CallInterfaceDescriptor { - public: - DECLARE_DESCRIPTOR(GrowArrayElementsDescriptor, CallInterfaceDescriptor) - - enum RegisterInfo { kObjectIndex, kKeyIndex, kCapacityIndex }; - static const Register ObjectRegister(); - static const Register KeyRegister(); - static const Register CapacityRegister(); -}; - #undef DECLARE_DESCRIPTOR diff --git a/src/objects-inl.h b/src/objects-inl.h index 62f04b831a..de41d689b5 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1827,12 +1827,6 @@ void JSObject::EnsureCanContainElements(Handle object, } -bool JSObject::WouldConvertToSlowElements(Handle key) { - uint32_t index; - return key->ToArrayIndex(&index) && WouldConvertToSlowElements(index); -} - - void JSObject::SetMapAndElements(Handle object, Handle new_map, Handle value) { diff --git a/src/objects.cc b/src/objects.cc index ec31b72bd4..96a1aa19c9 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -11267,8 +11267,10 @@ void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT #endif // ENABLE_DISASSEMBLER -Handle JSObject::SetFastElementsCapacity( - Handle object, int capacity, +Handle JSObject::SetFastElementsCapacityAndLength( + Handle object, + int capacity, + int length, SetFastElementsCapacitySmiMode smi_mode) { // We should never end in here with a pixel or external array. DCHECK(!object->HasExternalArrayElements()); @@ -11320,15 +11322,6 @@ Handle JSObject::SetFastElementsCapacity( object->GetElementsKind(), new_elements); } - return new_elements; -} - - -Handle JSObject::SetFastElementsCapacityAndLength( - Handle object, int capacity, int length, - SetFastElementsCapacitySmiMode smi_mode) { - Handle new_elements = - SetFastElementsCapacity(object, capacity, smi_mode); if (object->IsJSArray()) { Handle::cast(object)->set_length(Smi::FromInt(length)); } @@ -11336,8 +11329,9 @@ Handle JSObject::SetFastElementsCapacityAndLength( } -Handle JSObject::SetFastDoubleElementsCapacity( - Handle object, int capacity) { +void JSObject::SetFastDoubleElementsCapacityAndLength(Handle object, + int capacity, + int length) { // We should never end in here with a pixel or external array. DCHECK(!object->HasExternalArrayElements()); @@ -11367,18 +11361,9 @@ Handle JSObject::SetFastDoubleElementsCapacity( object->GetElementsKind(), elems); } - return elems; -} - - -Handle JSObject::SetFastDoubleElementsCapacityAndLength( - Handle object, int capacity, int length) { - Handle new_elements = - SetFastDoubleElementsCapacity(object, capacity); if (object->IsJSArray()) { Handle::cast(object)->set_length(Smi::FromInt(length)); } - return new_elements; } @@ -13303,8 +13288,9 @@ void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { } -bool JSObject::WouldConvertToSlowElements(uint32_t index) { - if (HasFastElements()) { +bool JSObject::WouldConvertToSlowElements(Handle key) { + uint32_t index; + if (HasFastElements() && key->ToArrayIndex(&index)) { Handle backing_store(FixedArrayBase::cast(elements())); uint32_t capacity = static_cast(backing_store->length()); if (index >= capacity) { diff --git a/src/objects.h b/src/objects.h index b63b1c3b45..067f357822 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1906,8 +1906,7 @@ class JSObject: public JSReceiver { // Would we convert a fast elements array to dictionary mode given // an access at key? - bool WouldConvertToSlowElements(uint32_t index); - inline bool WouldConvertToSlowElements(Handle key); + bool WouldConvertToSlowElements(Handle key); // Do we want to keep the elements in fast case when increasing the // capacity? bool ShouldConvertToSlowElements(int new_capacity); @@ -1967,12 +1966,6 @@ class JSObject: public JSReceiver { kDontAllowSmiElements }; - static Handle SetFastElementsCapacity( - Handle object, int capacity, - SetFastElementsCapacitySmiMode smi_mode); - static Handle SetFastDoubleElementsCapacity( - Handle object, int capacity); - // Replace the elements' backing store with fast elements of the given // capacity. Update the length for JSArrays. Returns the new backing // store. @@ -1981,8 +1974,10 @@ class JSObject: public JSReceiver { int capacity, int length, SetFastElementsCapacitySmiMode smi_mode); - static Handle SetFastDoubleElementsCapacityAndLength( - Handle object, int capacity, int length); + static void SetFastDoubleElementsCapacityAndLength( + Handle object, + int capacity, + int length); // Lookup interceptors are used for handling properties controlled by host // objects. diff --git a/src/runtime/runtime-array.cc b/src/runtime/runtime-array.cc index 29890b1558..523d8f5faa 100644 --- a/src/runtime/runtime-array.cc +++ b/src/runtime/runtime-array.cc @@ -1055,44 +1055,6 @@ RUNTIME_FUNCTION(Runtime_NormalizeElements) { } -// GrowArrayElements returns a sentinel Smi if the object was normalized. -RUNTIME_FUNCTION(Runtime_GrowArrayElements) { - HandleScope scope(isolate); - DCHECK(args.length() == 3); - CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); - CONVERT_SMI_ARG_CHECKED(key, 1); - - if (key < 0) { - return object->elements(); - } - - uint32_t capacity = static_cast(object->elements()->length()); - uint32_t index = static_cast(key); - - if (index >= capacity) { - if (object->WouldConvertToSlowElements(index)) { - JSObject::NormalizeElements(object); - return Smi::FromInt(0); - } - - uint32_t new_capacity = JSObject::NewElementsCapacity(index + 1); - ElementsKind kind = object->GetElementsKind(); - if (IsFastDoubleElementsKind(kind)) { - JSObject::SetFastDoubleElementsCapacity(object, new_capacity); - } else { - JSObject::SetFastElementsCapacitySmiMode set_capacity_mode = - object->HasFastSmiElements() ? JSObject::kAllowSmiElements - : JSObject::kDontAllowSmiElements; - JSObject::SetFastElementsCapacity(object, new_capacity, - set_capacity_mode); - } - } - - // On success, return the fixed array elements. - return object->elements(); -} - - RUNTIME_FUNCTION(Runtime_HasComplexElements) { HandleScope scope(isolate); DCHECK(args.length() == 1); diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 85ffece01a..4bc8fdf716 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -272,7 +272,6 @@ namespace internal { F(MoveArrayContents, 2, 1) \ F(EstimateNumberOfElements, 1, 1) \ F(NormalizeElements, 1, 1) \ - F(GrowArrayElements, 3, 1) \ F(HasComplexElements, 1, 1) \ \ /* Getters and Setters */ \ diff --git a/src/x64/interface-descriptors-x64.cc b/src/x64/interface-descriptors-x64.cc index 317a1e7a04..f19979d467 100644 --- a/src/x64/interface-descriptors-x64.cc +++ b/src/x64/interface-descriptors-x64.cc @@ -56,12 +56,6 @@ const Register MathPowIntegerDescriptor::exponent() { } -// IC register specifications -const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; } -const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; } -const Register GrowArrayElementsDescriptor::CapacityRegister() { return rcx; } - - void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) { Register registers[] = {rsi, rbx}; data->Initialize(arraysize(registers), registers, NULL); diff --git a/test/mjsunit/ensure-growing-store-learns.js b/test/mjsunit/ensure-growing-store-learns.js deleted file mode 100644 index 32c7f64018..0000000000 --- a/test/mjsunit/ensure-growing-store-learns.js +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax --noverify-heap --noenable-slow-asserts - -// --noverify-heap and --noenable-slow-asserts are set because the test is too -// slow with it on. - -// Ensure that keyed stores work, and optimized functions learn if the -// store required change to dictionary mode. Verify that stores that grow -// the array into large object space don't cause a deopt. -(function() { - var a = []; - - function foo(a, i) { - a[i] = 5.3; - } - - foo(a, 1); - foo(a, 2); - foo(a, 3); - %OptimizeFunctionOnNextCall(foo); - a[3] = 0; - foo(a, 3); - assertEquals(a[3], 5.3); - foo(a, 50000); - assertUnoptimized(foo); - assertTrue(%HasDictionaryElements(a)); - - var b = []; - foo(b, 1); - foo(b, 2); - // Put b in dictionary mode. - b[10000] = 5; - assertTrue(%HasDictionaryElements(b)); - foo(b, 3); - %OptimizeFunctionOnNextCall(foo); - foo(b, 50000); - assertOptimized(foo); - assertTrue(%HasDictionaryElements(b)); - - // Clearing feedback for the StoreIC in foo is important for runs with - // flag --stress-opt. - %ClearFunctionTypeFeedback(foo); -})(); - - -(function() { - var a = new Array(10); - - function foo2(a, i) { - a[i] = 50; - } - - // The KeyedStoreIC will learn GROW_MODE. - foo2(a, 10); - foo2(a, 12); - foo2(a, 31); - %OptimizeFunctionOnNextCall(foo2); - foo2(a, 40); - - // This test is way too slow without crankshaft. - if (4 != %GetOptimizationStatus(foo2)) { - assertOptimized(foo2); - assertTrue(%HasFastSmiElements(a)); - - // Grow a large array into large object space through the keyed store - // without deoptimizing. Grow by 10s. If we set elements too sparsely, the - // array will convert to dictionary mode. - a = new Array(99999); - assertTrue(%HasFastSmiElements(a)); - for (var i = 0; i < 263000; i += 10) { - foo2(a, i); - } - - // Verify that we are over 1 page in size, and foo2 remains optimized. - // This means we've smoothly transitioned to allocating in large object - // space. - assertTrue(%HasFastSmiElements(a)); - assertTrue(a.length * 4 > (1024 * 1024)); - assertOptimized(foo2); - } - - %ClearFunctionTypeFeedback(foo2); -})();