| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 Isolate* isolate, | 53 Isolate* isolate, |
| 54 CodeStubInterfaceDescriptor* descriptor) { | 54 CodeStubInterfaceDescriptor* descriptor) { |
| 55 static Register registers[] = { r3, r2, r1, r0 }; | 55 static Register registers[] = { r3, r2, r1, r0 }; |
| 56 descriptor->register_param_count_ = 4; | 56 descriptor->register_param_count_ = 4; |
| 57 descriptor->register_params_ = registers; | 57 descriptor->register_params_ = registers; |
| 58 descriptor->deoptimization_handler_ = | 58 descriptor->deoptimization_handler_ = |
| 59 Runtime::FunctionForId(Runtime::kCreateObjectLiteralShallow)->entry; | 59 Runtime::FunctionForId(Runtime::kCreateObjectLiteralShallow)->entry; |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( |
| 64 Isolate* isolate, |
| 65 CodeStubInterfaceDescriptor* descriptor) { |
| 66 static Register registers[] = { r2 }; |
| 67 descriptor->register_param_count_ = 1; |
| 68 descriptor->register_params_ = registers; |
| 69 descriptor->deoptimization_handler_ = NULL; |
| 70 } |
| 71 |
| 72 |
| 63 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( | 73 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( |
| 64 Isolate* isolate, | 74 Isolate* isolate, |
| 65 CodeStubInterfaceDescriptor* descriptor) { | 75 CodeStubInterfaceDescriptor* descriptor) { |
| 66 static Register registers[] = { r1, r0 }; | 76 static Register registers[] = { r1, r0 }; |
| 67 descriptor->register_param_count_ = 2; | 77 descriptor->register_param_count_ = 2; |
| 68 descriptor->register_params_ = registers; | 78 descriptor->register_params_ = registers; |
| 69 descriptor->deoptimization_handler_ = | 79 descriptor->deoptimization_handler_ = |
| 70 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); | 80 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); |
| 71 } | 81 } |
| 72 | 82 |
| (...skipping 2921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2994 } | 3004 } |
| 2995 | 3005 |
| 2996 | 3006 |
| 2997 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { | 3007 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { |
| 2998 CEntryStub::GenerateAheadOfTime(isolate); | 3008 CEntryStub::GenerateAheadOfTime(isolate); |
| 2999 WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate); | 3009 WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate); |
| 3000 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); | 3010 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); |
| 3001 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); | 3011 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); |
| 3002 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate); | 3012 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate); |
| 3003 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 3013 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
| 3014 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); |
| 3004 } | 3015 } |
| 3005 | 3016 |
| 3006 | 3017 |
| 3007 void CodeStub::GenerateFPStubs(Isolate* isolate) { | 3018 void CodeStub::GenerateFPStubs(Isolate* isolate) { |
| 3008 SaveFPRegsMode mode = kSaveFPRegs; | 3019 SaveFPRegsMode mode = kSaveFPRegs; |
| 3009 CEntryStub save_doubles(1, mode); | 3020 CEntryStub save_doubles(1, mode); |
| 3010 StoreBufferOverflowStub stub(mode); | 3021 StoreBufferOverflowStub stub(mode); |
| 3011 // These stubs might already be in the snapshot, detect that and don't | 3022 // These stubs might already be in the snapshot, detect that and don't |
| 3012 // regenerate, which would lead to code stub initialization state being messed | 3023 // regenerate, which would lead to code stub initialization state being messed |
| 3013 // up. | 3024 // up. |
| (...skipping 1628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4642 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()), | 4653 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()), |
| 4643 masm->isolate()->heap()->the_hole_value()); | 4654 masm->isolate()->heap()->the_hole_value()); |
| 4644 | 4655 |
| 4645 // Load the cache state into r3. | 4656 // Load the cache state into r3. |
| 4646 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); | 4657 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); |
| 4647 | 4658 |
| 4648 // A monomorphic cache hit or an already megamorphic state: invoke the | 4659 // A monomorphic cache hit or an already megamorphic state: invoke the |
| 4649 // function without changing the state. | 4660 // function without changing the state. |
| 4650 __ cmp(r3, r1); | 4661 __ cmp(r3, r1); |
| 4651 __ b(eq, &done); | 4662 __ b(eq, &done); |
| 4652 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); | 4663 |
| 4653 __ b(eq, &done); | 4664 /* |
| 4665 If we came here, we need to see if we are the array function. |
| 4666 If we didn't have a matching function, and we didn't find the megamorph |
| 4667 sentinel, then we have in the cell either some other function or an |
| 4668 AllocationSite. Do a map check on the object in ecx |
| 4669 */ |
| 4670 Handle<Map> allocation_site_map( |
| 4671 masm->isolate()->heap()->allocation_site_map(), |
| 4672 masm->isolate()); |
| 4673 __ ldr(r5, FieldMemOperand(r3, 0)); |
| 4674 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); |
| 4675 __ b(ne, &miss); |
| 4654 | 4676 |
| 4655 // Special handling of the Array() function, which caches not only the | 4677 // Special handling of the Array() function, which caches not only the |
| 4656 // monomorphic Array function but the initial ElementsKind with special | 4678 // monomorphic Array function but the initial ElementsKind with special |
| 4657 // sentinels | 4679 // sentinels |
| 4658 __ JumpIfNotSmi(r3, &miss); | |
| 4659 if (FLAG_debug_code) { | |
| 4660 Handle<Object> terminal_kind_sentinel = | |
| 4661 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), | |
| 4662 LAST_FAST_ELEMENTS_KIND); | |
| 4663 __ cmp(r3, Operand(terminal_kind_sentinel)); | |
| 4664 __ Assert(le, "Array function sentinel is not an ElementsKind"); | |
| 4665 } | |
| 4666 | |
| 4667 // Make sure the function is the Array() function | 4680 // Make sure the function is the Array() function |
| 4668 __ LoadArrayFunction(r3); | 4681 __ LoadArrayFunction(r3); |
| 4669 __ cmp(r1, r3); | 4682 __ cmp(r1, r3); |
| 4670 __ b(ne, &megamorphic); | 4683 __ b(ne, &megamorphic); |
| 4671 __ jmp(&done); | 4684 __ jmp(&done); |
| 4672 | 4685 |
| 4673 __ bind(&miss); | 4686 __ bind(&miss); |
| 4674 | 4687 |
| 4675 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 4688 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
| 4676 // megamorphic. | 4689 // megamorphic. |
| 4677 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 4690 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
| 4678 __ b(eq, &initialize); | 4691 __ b(eq, &initialize); |
| 4679 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 4692 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
| 4680 // write-barrier is needed. | 4693 // write-barrier is needed. |
| 4681 __ bind(&megamorphic); | 4694 __ bind(&megamorphic); |
| 4682 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 4695 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 4683 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset)); | 4696 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset)); |
| 4684 __ jmp(&done); | 4697 __ jmp(&done); |
| 4685 | 4698 |
| 4686 // An uninitialized cache is patched with the function or sentinel to | 4699 // An uninitialized cache is patched with the function or sentinel to |
| 4687 // indicate the ElementsKind if function is the Array constructor. | 4700 // indicate the ElementsKind if function is the Array constructor. |
| 4688 __ bind(&initialize); | 4701 __ bind(&initialize); |
| 4689 // Make sure the function is the Array() function | 4702 // Make sure the function is the Array() function |
| 4690 __ LoadArrayFunction(r3); | 4703 __ LoadArrayFunction(r3); |
| 4691 __ cmp(r1, r3); | 4704 __ cmp(r1, r3); |
| 4692 __ b(ne, ¬_array_function); | 4705 __ b(ne, ¬_array_function); |
| 4693 | 4706 |
| 4694 // The target function is the Array constructor, install a sentinel value in | 4707 // The target function is the Array constructor, |
| 4695 // the constructor's type info cell that will track the initial ElementsKind | 4708 // Create an AllocationSite if we don't already have it, store it in the cell |
| 4696 // that should be used for the array when its constructed. | 4709 { |
| 4697 Handle<Object> initial_kind_sentinel = | 4710 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4698 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), | 4711 |
| 4699 GetInitialFastElementsKind()); | 4712 __ push(r0); |
| 4700 __ mov(r3, Operand(initial_kind_sentinel)); | 4713 __ push(r1); |
| 4701 __ str(r3, FieldMemOperand(r2, Cell::kValueOffset)); | 4714 __ push(r2); |
| 4715 |
| 4716 CreateAllocationSiteStub create_stub; |
| 4717 __ CallStub(&create_stub); |
| 4718 |
| 4719 __ pop(r2); |
| 4720 __ pop(r1); |
| 4721 __ pop(r0); |
| 4722 } |
| 4702 __ b(&done); | 4723 __ b(&done); |
| 4703 | 4724 |
| 4704 __ bind(¬_array_function); | 4725 __ bind(¬_array_function); |
| 4705 __ str(r1, FieldMemOperand(r2, Cell::kValueOffset)); | 4726 __ str(r1, FieldMemOperand(r2, Cell::kValueOffset)); |
| 4706 // No need for a write barrier here - cells are rescanned. | 4727 // No need for a write barrier here - cells are rescanned. |
| 4707 | 4728 |
| 4708 __ bind(&done); | 4729 __ bind(&done); |
| 4709 } | 4730 } |
| 4710 | 4731 |
| 4711 | 4732 |
| (...skipping 2462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7174 // r0 - number of arguments | 7195 // r0 - number of arguments |
| 7175 // r1 - constructor? | 7196 // r1 - constructor? |
| 7176 // sp[0] - last argument | 7197 // sp[0] - last argument |
| 7177 ASSERT(FAST_SMI_ELEMENTS == 0); | 7198 ASSERT(FAST_SMI_ELEMENTS == 0); |
| 7178 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 7199 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
| 7179 ASSERT(FAST_ELEMENTS == 2); | 7200 ASSERT(FAST_ELEMENTS == 2); |
| 7180 ASSERT(FAST_HOLEY_ELEMENTS == 3); | 7201 ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 7181 ASSERT(FAST_DOUBLE_ELEMENTS == 4); | 7202 ASSERT(FAST_DOUBLE_ELEMENTS == 4); |
| 7182 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); | 7203 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); |
| 7183 | 7204 |
| 7184 Handle<Object> undefined_sentinel( | |
| 7185 masm->isolate()->heap()->undefined_value(), | |
| 7186 masm->isolate()); | |
| 7187 | |
| 7188 // is the low bit set? If so, we are holey and that is good. | 7205 // is the low bit set? If so, we are holey and that is good. |
| 7189 __ tst(r3, Operand(1)); | 7206 __ tst(r3, Operand(1)); |
| 7190 Label normal_sequence; | 7207 Label normal_sequence; |
| 7191 __ b(ne, &normal_sequence); | 7208 __ b(ne, &normal_sequence); |
| 7192 | 7209 |
| 7193 // look at the first argument | 7210 // look at the first argument |
| 7194 __ ldr(r5, MemOperand(sp, 0)); | 7211 __ ldr(r5, MemOperand(sp, 0)); |
| 7195 __ cmp(r5, Operand::Zero()); | 7212 __ cmp(r5, Operand::Zero()); |
| 7196 __ b(eq, &normal_sequence); | 7213 __ b(eq, &normal_sequence); |
| 7197 | 7214 |
| 7198 // We are going to create a holey array, but our kind is non-holey. | 7215 // We are going to create a holey array, but our kind is non-holey. |
| 7199 // Fix kind and retry | 7216 // Fix kind and retry |
| 7200 __ add(r3, r3, Operand(1)); | 7217 __ add(r3, r3, Operand(1)); |
| 7201 __ cmp(r2, Operand(undefined_sentinel)); | 7218 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
| 7202 __ b(eq, &normal_sequence); | 7219 __ b(eq, &normal_sequence); |
| 7203 | 7220 |
| 7204 // The type cell may have gone megamorphic, don't overwrite if so | 7221 __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset)); |
| 7205 __ ldr(r5, FieldMemOperand(r2, kPointerSize)); | 7222 __ ldr(r5, FieldMemOperand(r5, 0)); |
| 7206 __ JumpIfNotSmi(r5, &normal_sequence); | 7223 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); |
| 7224 __ b(ne, &normal_sequence); |
| 7207 | 7225 |
| 7208 // Save the resulting elements kind in type info | 7226 // Save the resulting elements kind in type info |
| 7209 __ SmiTag(r3); | 7227 __ SmiTag(r3); |
| 7210 __ str(r3, FieldMemOperand(r2, kPointerSize)); | 7228 __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset)); |
| 7229 __ str(r3, FieldMemOperand(r5, AllocationSite::kPayloadOffset)); |
| 7211 __ SmiUntag(r3); | 7230 __ SmiUntag(r3); |
| 7212 | 7231 |
| 7213 __ bind(&normal_sequence); | 7232 __ bind(&normal_sequence); |
| 7214 int last_index = GetSequenceIndexFromFastElementsKind( | 7233 int last_index = GetSequenceIndexFromFastElementsKind( |
| 7215 TERMINAL_FAST_ELEMENTS_KIND); | 7234 TERMINAL_FAST_ELEMENTS_KIND); |
| 7216 for (int i = 0; i <= last_index; ++i) { | 7235 for (int i = 0; i <= last_index; ++i) { |
| 7217 Label next; | 7236 Label next; |
| 7218 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 7237 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 7219 __ cmp(r3, Operand(kind)); | 7238 __ cmp(r3, Operand(kind)); |
| 7220 __ b(ne, &next); | 7239 __ b(ne, &next); |
| 7221 ArraySingleArgumentConstructorStub stub(kind); | 7240 ArraySingleArgumentConstructorStub stub(kind); |
| 7222 __ TailCallStub(&stub); | 7241 __ TailCallStub(&stub); |
| 7223 __ bind(&next); | 7242 __ bind(&next); |
| 7224 } | 7243 } |
| 7225 | 7244 |
| 7226 // If we reached this point there is a problem. | 7245 // If we reached this point there is a problem. |
| 7227 __ Abort("Unexpected ElementsKind in array constructor"); | 7246 __ Abort("Unexpected ElementsKind in array constructor"); |
| 7228 } | 7247 } |
| 7229 | 7248 |
| 7230 | 7249 |
| 7231 template<class T> | 7250 template<class T> |
| 7232 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { | 7251 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { |
| 7233 int to_index = GetSequenceIndexFromFastElementsKind( | 7252 int to_index = GetSequenceIndexFromFastElementsKind( |
| 7234 TERMINAL_FAST_ELEMENTS_KIND); | 7253 TERMINAL_FAST_ELEMENTS_KIND); |
| 7235 for (int i = 0; i <= to_index; ++i) { | 7254 for (int i = 0; i <= to_index; ++i) { |
| 7236 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 7255 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 7237 T stub(kind); | 7256 T stub(kind); |
| 7238 stub.GetCode(isolate)->set_is_pregenerated(true); | 7257 stub.GetCode(isolate)->set_is_pregenerated(true); |
| 7239 if (AllocationSiteInfo::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { | 7258 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { |
| 7240 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); | 7259 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); |
| 7241 stub1.GetCode(isolate)->set_is_pregenerated(true); | 7260 stub1.GetCode(isolate)->set_is_pregenerated(true); |
| 7242 } | 7261 } |
| 7243 } | 7262 } |
| 7244 } | 7263 } |
| 7245 | 7264 |
| 7246 | 7265 |
| 7247 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { | 7266 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { |
| 7248 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( | 7267 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( |
| 7249 isolate); | 7268 isolate); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 7270 | 7289 |
| 7271 | 7290 |
| 7272 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 7291 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
| 7273 // ----------- S t a t e ------------- | 7292 // ----------- S t a t e ------------- |
| 7274 // -- r0 : argc (only if argument_count_ == ANY) | 7293 // -- r0 : argc (only if argument_count_ == ANY) |
| 7275 // -- r1 : constructor | 7294 // -- r1 : constructor |
| 7276 // -- r2 : type info cell | 7295 // -- r2 : type info cell |
| 7277 // -- sp[0] : return address | 7296 // -- sp[0] : return address |
| 7278 // -- sp[4] : last argument | 7297 // -- sp[4] : last argument |
| 7279 // ----------------------------------- | 7298 // ----------------------------------- |
| 7280 Handle<Object> undefined_sentinel( | |
| 7281 masm->isolate()->heap()->undefined_value(), | |
| 7282 masm->isolate()); | |
| 7283 | |
| 7284 if (FLAG_debug_code) { | 7299 if (FLAG_debug_code) { |
| 7285 // The array construct code is only set for the global and natives | 7300 // The array construct code is only set for the global and natives |
| 7286 // builtin Array functions which always have maps. | 7301 // builtin Array functions which always have maps. |
| 7287 | 7302 |
| 7288 // Initial map for the builtin Array function should be a map. | 7303 // Initial map for the builtin Array function should be a map. |
| 7289 __ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); | 7304 __ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); |
| 7290 // Will both indicate a NULL and a Smi. | 7305 // Will both indicate a NULL and a Smi. |
| 7291 __ tst(r3, Operand(kSmiTagMask)); | 7306 __ tst(r3, Operand(kSmiTagMask)); |
| 7292 __ Assert(ne, "Unexpected initial map for Array function"); | 7307 __ Assert(ne, "Unexpected initial map for Array function"); |
| 7293 __ CompareObjectType(r3, r3, r4, MAP_TYPE); | 7308 __ CompareObjectType(r3, r3, r4, MAP_TYPE); |
| 7294 __ Assert(eq, "Unexpected initial map for Array function"); | 7309 __ Assert(eq, "Unexpected initial map for Array function"); |
| 7295 | 7310 |
| 7296 // We should either have undefined in ebx or a valid cell | 7311 // We should either have undefined in ebx or a valid cell |
| 7297 Label okay_here; | 7312 Label okay_here; |
| 7298 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); | 7313 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); |
| 7299 __ cmp(r2, Operand(undefined_sentinel)); | 7314 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
| 7300 __ b(eq, &okay_here); | 7315 __ b(eq, &okay_here); |
| 7301 __ ldr(r3, FieldMemOperand(r2, 0)); | 7316 __ ldr(r3, FieldMemOperand(r2, 0)); |
| 7302 __ cmp(r3, Operand(cell_map)); | 7317 __ cmp(r3, Operand(cell_map)); |
| 7303 __ Assert(eq, "Expected property cell in register ebx"); | 7318 __ Assert(eq, "Expected property cell in register ebx"); |
| 7304 __ bind(&okay_here); | 7319 __ bind(&okay_here); |
| 7305 } | 7320 } |
| 7306 | 7321 |
| 7307 Label no_info, switch_ready; | 7322 Label no_info, switch_ready; |
| 7308 // Get the elements kind and case on that. | 7323 // Get the elements kind and case on that. |
| 7309 __ cmp(r2, Operand(undefined_sentinel)); | 7324 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
| 7310 __ b(eq, &no_info); | 7325 __ b(eq, &no_info); |
| 7311 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); | 7326 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); |
| 7312 __ JumpIfNotSmi(r3, &no_info); | 7327 |
| 7328 // The type cell may have undefined in its value. |
| 7329 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); |
| 7330 __ b(eq, &no_info); |
| 7331 |
| 7332 // We should have an allocation site object |
| 7333 if (FLAG_debug_code) { |
| 7334 __ push(r3); |
| 7335 __ ldr(r3, FieldMemOperand(r3, 0)); |
| 7336 __ CompareRoot(r3, Heap::kAllocationSiteMapRootIndex); |
| 7337 __ Assert(eq, "Expected AllocationSite object in register edx"); |
| 7338 } |
| 7339 |
| 7340 __ ldr(r3, FieldMemOperand(r3, AllocationSite::kPayloadOffset)); |
| 7313 __ SmiUntag(r3); | 7341 __ SmiUntag(r3); |
| 7314 __ jmp(&switch_ready); | 7342 __ jmp(&switch_ready); |
| 7315 __ bind(&no_info); | 7343 __ bind(&no_info); |
| 7316 __ mov(r3, Operand(GetInitialFastElementsKind())); | 7344 __ mov(r3, Operand(GetInitialFastElementsKind())); |
| 7317 __ bind(&switch_ready); | 7345 __ bind(&switch_ready); |
| 7318 | 7346 |
| 7319 if (argument_count_ == ANY) { | 7347 if (argument_count_ == ANY) { |
| 7320 Label not_zero_case, not_one_case; | 7348 Label not_zero_case, not_one_case; |
| 7321 __ tst(r0, r0); | 7349 __ tst(r0, r0); |
| 7322 __ b(ne, ¬_zero_case); | 7350 __ b(ne, ¬_zero_case); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7424 __ bind(&fast_elements_case); | 7452 __ bind(&fast_elements_case); |
| 7425 GenerateCase(masm, FAST_ELEMENTS); | 7453 GenerateCase(masm, FAST_ELEMENTS); |
| 7426 } | 7454 } |
| 7427 | 7455 |
| 7428 | 7456 |
| 7429 #undef __ | 7457 #undef __ |
| 7430 | 7458 |
| 7431 } } // namespace v8::internal | 7459 } } // namespace v8::internal |
| 7432 | 7460 |
| 7433 #endif // V8_TARGET_ARCH_ARM | 7461 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |