| 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 2673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2746 } | 2756 } |
| 2747 | 2757 |
| 2748 | 2758 |
| 2749 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { | 2759 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { |
| 2750 CEntryStub::GenerateAheadOfTime(isolate); | 2760 CEntryStub::GenerateAheadOfTime(isolate); |
| 2751 WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate); | 2761 WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate); |
| 2752 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); | 2762 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); |
| 2753 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); | 2763 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); |
| 2754 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate); | 2764 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate); |
| 2755 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 2765 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
| 2766 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); |
| 2756 } | 2767 } |
| 2757 | 2768 |
| 2758 | 2769 |
| 2759 void CodeStub::GenerateFPStubs(Isolate* isolate) { | 2770 void CodeStub::GenerateFPStubs(Isolate* isolate) { |
| 2760 SaveFPRegsMode mode = kSaveFPRegs; | 2771 SaveFPRegsMode mode = kSaveFPRegs; |
| 2761 CEntryStub save_doubles(1, mode); | 2772 CEntryStub save_doubles(1, mode); |
| 2762 StoreBufferOverflowStub stub(mode); | 2773 StoreBufferOverflowStub stub(mode); |
| 2763 // These stubs might already be in the snapshot, detect that and don't | 2774 // These stubs might already be in the snapshot, detect that and don't |
| 2764 // regenerate, which would lead to code stub initialization state being messed | 2775 // regenerate, which would lead to code stub initialization state being messed |
| 2765 // up. | 2776 // up. |
| (...skipping 1628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4394 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()), | 4405 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()), |
| 4395 masm->isolate()->heap()->the_hole_value()); | 4406 masm->isolate()->heap()->the_hole_value()); |
| 4396 | 4407 |
| 4397 // Load the cache state into r3. | 4408 // Load the cache state into r3. |
| 4398 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); | 4409 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); |
| 4399 | 4410 |
| 4400 // A monomorphic cache hit or an already megamorphic state: invoke the | 4411 // A monomorphic cache hit or an already megamorphic state: invoke the |
| 4401 // function without changing the state. | 4412 // function without changing the state. |
| 4402 __ cmp(r3, r1); | 4413 __ cmp(r3, r1); |
| 4403 __ b(eq, &done); | 4414 __ b(eq, &done); |
| 4404 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); | |
| 4405 __ b(eq, &done); | |
| 4406 | 4415 |
| 4407 // Special handling of the Array() function, which caches not only the | 4416 // If we came here, we need to see if we are the array function. |
| 4408 // monomorphic Array function but the initial ElementsKind with special | 4417 // If we didn't have a matching function, and we didn't find the megamorph |
| 4409 // sentinels | 4418 // sentinel, then we have in the cell either some other function or an |
| 4410 __ JumpIfNotSmi(r3, &miss); | 4419 // AllocationSite. Do a map check on the object in ecx. |
| 4411 if (FLAG_debug_code) { | 4420 Handle<Map> allocation_site_map( |
| 4412 Handle<Object> terminal_kind_sentinel = | 4421 masm->isolate()->heap()->allocation_site_map(), |
| 4413 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), | 4422 masm->isolate()); |
| 4414 LAST_FAST_ELEMENTS_KIND); | 4423 __ ldr(r5, FieldMemOperand(r3, 0)); |
| 4415 __ cmp(r3, Operand(terminal_kind_sentinel)); | 4424 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); |
| 4416 __ Assert(le, "Array function sentinel is not an ElementsKind"); | 4425 __ b(ne, &miss); |
| 4417 } | |
| 4418 | 4426 |
| 4419 // Make sure the function is the Array() function | 4427 // Make sure the function is the Array() function |
| 4420 __ LoadArrayFunction(r3); | 4428 __ LoadArrayFunction(r3); |
| 4421 __ cmp(r1, r3); | 4429 __ cmp(r1, r3); |
| 4422 __ b(ne, &megamorphic); | 4430 __ b(ne, &megamorphic); |
| 4423 __ jmp(&done); | 4431 __ jmp(&done); |
| 4424 | 4432 |
| 4425 __ bind(&miss); | 4433 __ bind(&miss); |
| 4426 | 4434 |
| 4427 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 4435 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
| 4428 // megamorphic. | 4436 // megamorphic. |
| 4429 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 4437 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
| 4430 __ b(eq, &initialize); | 4438 __ b(eq, &initialize); |
| 4431 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 4439 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
| 4432 // write-barrier is needed. | 4440 // write-barrier is needed. |
| 4433 __ bind(&megamorphic); | 4441 __ bind(&megamorphic); |
| 4434 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 4442 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 4435 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset)); | 4443 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset)); |
| 4436 __ jmp(&done); | 4444 __ jmp(&done); |
| 4437 | 4445 |
| 4438 // An uninitialized cache is patched with the function or sentinel to | 4446 // An uninitialized cache is patched with the function or sentinel to |
| 4439 // indicate the ElementsKind if function is the Array constructor. | 4447 // indicate the ElementsKind if function is the Array constructor. |
| 4440 __ bind(&initialize); | 4448 __ bind(&initialize); |
| 4441 // Make sure the function is the Array() function | 4449 // Make sure the function is the Array() function |
| 4442 __ LoadArrayFunction(r3); | 4450 __ LoadArrayFunction(r3); |
| 4443 __ cmp(r1, r3); | 4451 __ cmp(r1, r3); |
| 4444 __ b(ne, ¬_array_function); | 4452 __ b(ne, ¬_array_function); |
| 4445 | 4453 |
| 4446 // The target function is the Array constructor, install a sentinel value in | 4454 // The target function is the Array constructor, |
| 4447 // the constructor's type info cell that will track the initial ElementsKind | 4455 // Create an AllocationSite if we don't already have it, store it in the cell |
| 4448 // that should be used for the array when its constructed. | 4456 { |
| 4449 Handle<Object> initial_kind_sentinel = | 4457 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4450 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), | 4458 |
| 4451 GetInitialFastElementsKind()); | 4459 __ push(r0); |
| 4452 __ mov(r3, Operand(initial_kind_sentinel)); | 4460 __ push(r1); |
| 4453 __ str(r3, FieldMemOperand(r2, Cell::kValueOffset)); | 4461 __ push(r2); |
| 4462 |
| 4463 CreateAllocationSiteStub create_stub; |
| 4464 __ CallStub(&create_stub); |
| 4465 |
| 4466 __ pop(r2); |
| 4467 __ pop(r1); |
| 4468 __ pop(r0); |
| 4469 } |
| 4454 __ b(&done); | 4470 __ b(&done); |
| 4455 | 4471 |
| 4456 __ bind(¬_array_function); | 4472 __ bind(¬_array_function); |
| 4457 __ str(r1, FieldMemOperand(r2, Cell::kValueOffset)); | 4473 __ str(r1, FieldMemOperand(r2, Cell::kValueOffset)); |
| 4458 // No need for a write barrier here - cells are rescanned. | 4474 // No need for a write barrier here - cells are rescanned. |
| 4459 | 4475 |
| 4460 __ bind(&done); | 4476 __ bind(&done); |
| 4461 } | 4477 } |
| 4462 | 4478 |
| 4463 | 4479 |
| (...skipping 2463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6927 // r0 - number of arguments | 6943 // r0 - number of arguments |
| 6928 // r1 - constructor? | 6944 // r1 - constructor? |
| 6929 // sp[0] - last argument | 6945 // sp[0] - last argument |
| 6930 ASSERT(FAST_SMI_ELEMENTS == 0); | 6946 ASSERT(FAST_SMI_ELEMENTS == 0); |
| 6931 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 6947 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
| 6932 ASSERT(FAST_ELEMENTS == 2); | 6948 ASSERT(FAST_ELEMENTS == 2); |
| 6933 ASSERT(FAST_HOLEY_ELEMENTS == 3); | 6949 ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 6934 ASSERT(FAST_DOUBLE_ELEMENTS == 4); | 6950 ASSERT(FAST_DOUBLE_ELEMENTS == 4); |
| 6935 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); | 6951 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); |
| 6936 | 6952 |
| 6937 Handle<Object> undefined_sentinel( | |
| 6938 masm->isolate()->heap()->undefined_value(), | |
| 6939 masm->isolate()); | |
| 6940 | |
| 6941 // is the low bit set? If so, we are holey and that is good. | 6953 // is the low bit set? If so, we are holey and that is good. |
| 6942 __ tst(r3, Operand(1)); | 6954 __ tst(r3, Operand(1)); |
| 6943 Label normal_sequence; | 6955 Label normal_sequence; |
| 6944 __ b(ne, &normal_sequence); | 6956 __ b(ne, &normal_sequence); |
| 6945 | 6957 |
| 6946 // look at the first argument | 6958 // look at the first argument |
| 6947 __ ldr(r5, MemOperand(sp, 0)); | 6959 __ ldr(r5, MemOperand(sp, 0)); |
| 6948 __ cmp(r5, Operand::Zero()); | 6960 __ cmp(r5, Operand::Zero()); |
| 6949 __ b(eq, &normal_sequence); | 6961 __ b(eq, &normal_sequence); |
| 6950 | 6962 |
| 6951 // We are going to create a holey array, but our kind is non-holey. | 6963 // We are going to create a holey array, but our kind is non-holey. |
| 6952 // Fix kind and retry | 6964 // Fix kind and retry (only if we have an allocation site in the cell). |
| 6953 __ add(r3, r3, Operand(1)); | 6965 __ add(r3, r3, Operand(1)); |
| 6954 __ cmp(r2, Operand(undefined_sentinel)); | 6966 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
| 6955 __ b(eq, &normal_sequence); | 6967 __ b(eq, &normal_sequence); |
| 6956 | 6968 __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset)); |
| 6957 // The type cell may have gone megamorphic, don't overwrite if so | 6969 __ ldr(r5, FieldMemOperand(r5, 0)); |
| 6958 __ ldr(r5, FieldMemOperand(r2, kPointerSize)); | 6970 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); |
| 6959 __ JumpIfNotSmi(r5, &normal_sequence); | 6971 __ b(ne, &normal_sequence); |
| 6960 | 6972 |
| 6961 // Save the resulting elements kind in type info | 6973 // Save the resulting elements kind in type info |
| 6962 __ SmiTag(r3); | 6974 __ SmiTag(r3); |
| 6963 __ str(r3, FieldMemOperand(r2, kPointerSize)); | 6975 __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset)); |
| 6976 __ str(r3, FieldMemOperand(r5, AllocationSite::kPayloadOffset)); |
| 6964 __ SmiUntag(r3); | 6977 __ SmiUntag(r3); |
| 6965 | 6978 |
| 6966 __ bind(&normal_sequence); | 6979 __ bind(&normal_sequence); |
| 6967 int last_index = GetSequenceIndexFromFastElementsKind( | 6980 int last_index = GetSequenceIndexFromFastElementsKind( |
| 6968 TERMINAL_FAST_ELEMENTS_KIND); | 6981 TERMINAL_FAST_ELEMENTS_KIND); |
| 6969 for (int i = 0; i <= last_index; ++i) { | 6982 for (int i = 0; i <= last_index; ++i) { |
| 6970 Label next; | 6983 Label next; |
| 6971 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 6984 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 6972 __ cmp(r3, Operand(kind)); | 6985 __ cmp(r3, Operand(kind)); |
| 6973 __ b(ne, &next); | 6986 __ b(ne, &next); |
| 6974 ArraySingleArgumentConstructorStub stub(kind); | 6987 ArraySingleArgumentConstructorStub stub(kind); |
| 6975 __ TailCallStub(&stub); | 6988 __ TailCallStub(&stub); |
| 6976 __ bind(&next); | 6989 __ bind(&next); |
| 6977 } | 6990 } |
| 6978 | 6991 |
| 6979 // If we reached this point there is a problem. | 6992 // If we reached this point there is a problem. |
| 6980 __ Abort("Unexpected ElementsKind in array constructor"); | 6993 __ Abort("Unexpected ElementsKind in array constructor"); |
| 6981 } | 6994 } |
| 6982 | 6995 |
| 6983 | 6996 |
| 6984 template<class T> | 6997 template<class T> |
| 6985 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { | 6998 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { |
| 6986 int to_index = GetSequenceIndexFromFastElementsKind( | 6999 int to_index = GetSequenceIndexFromFastElementsKind( |
| 6987 TERMINAL_FAST_ELEMENTS_KIND); | 7000 TERMINAL_FAST_ELEMENTS_KIND); |
| 6988 for (int i = 0; i <= to_index; ++i) { | 7001 for (int i = 0; i <= to_index; ++i) { |
| 6989 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 7002 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 6990 T stub(kind); | 7003 T stub(kind); |
| 6991 stub.GetCode(isolate)->set_is_pregenerated(true); | 7004 stub.GetCode(isolate)->set_is_pregenerated(true); |
| 6992 if (AllocationSiteInfo::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { | 7005 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { |
| 6993 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); | 7006 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); |
| 6994 stub1.GetCode(isolate)->set_is_pregenerated(true); | 7007 stub1.GetCode(isolate)->set_is_pregenerated(true); |
| 6995 } | 7008 } |
| 6996 } | 7009 } |
| 6997 } | 7010 } |
| 6998 | 7011 |
| 6999 | 7012 |
| 7000 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { | 7013 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { |
| 7001 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( | 7014 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( |
| 7002 isolate); | 7015 isolate); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 7023 | 7036 |
| 7024 | 7037 |
| 7025 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 7038 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
| 7026 // ----------- S t a t e ------------- | 7039 // ----------- S t a t e ------------- |
| 7027 // -- r0 : argc (only if argument_count_ == ANY) | 7040 // -- r0 : argc (only if argument_count_ == ANY) |
| 7028 // -- r1 : constructor | 7041 // -- r1 : constructor |
| 7029 // -- r2 : type info cell | 7042 // -- r2 : type info cell |
| 7030 // -- sp[0] : return address | 7043 // -- sp[0] : return address |
| 7031 // -- sp[4] : last argument | 7044 // -- sp[4] : last argument |
| 7032 // ----------------------------------- | 7045 // ----------------------------------- |
| 7033 Handle<Object> undefined_sentinel( | |
| 7034 masm->isolate()->heap()->undefined_value(), | |
| 7035 masm->isolate()); | |
| 7036 | |
| 7037 if (FLAG_debug_code) { | 7046 if (FLAG_debug_code) { |
| 7038 // The array construct code is only set for the global and natives | 7047 // The array construct code is only set for the global and natives |
| 7039 // builtin Array functions which always have maps. | 7048 // builtin Array functions which always have maps. |
| 7040 | 7049 |
| 7041 // Initial map for the builtin Array function should be a map. | 7050 // Initial map for the builtin Array function should be a map. |
| 7042 __ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); | 7051 __ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); |
| 7043 // Will both indicate a NULL and a Smi. | 7052 // Will both indicate a NULL and a Smi. |
| 7044 __ tst(r3, Operand(kSmiTagMask)); | 7053 __ tst(r3, Operand(kSmiTagMask)); |
| 7045 __ Assert(ne, "Unexpected initial map for Array function"); | 7054 __ Assert(ne, "Unexpected initial map for Array function"); |
| 7046 __ CompareObjectType(r3, r3, r4, MAP_TYPE); | 7055 __ CompareObjectType(r3, r3, r4, MAP_TYPE); |
| 7047 __ Assert(eq, "Unexpected initial map for Array function"); | 7056 __ Assert(eq, "Unexpected initial map for Array function"); |
| 7048 | 7057 |
| 7049 // We should either have undefined in ebx or a valid cell | 7058 // We should either have undefined in ebx or a valid cell |
| 7050 Label okay_here; | 7059 Label okay_here; |
| 7051 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); | 7060 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); |
| 7052 __ cmp(r2, Operand(undefined_sentinel)); | 7061 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
| 7053 __ b(eq, &okay_here); | 7062 __ b(eq, &okay_here); |
| 7054 __ ldr(r3, FieldMemOperand(r2, 0)); | 7063 __ ldr(r3, FieldMemOperand(r2, 0)); |
| 7055 __ cmp(r3, Operand(cell_map)); | 7064 __ cmp(r3, Operand(cell_map)); |
| 7056 __ Assert(eq, "Expected property cell in register ebx"); | 7065 __ Assert(eq, "Expected property cell in register ebx"); |
| 7057 __ bind(&okay_here); | 7066 __ bind(&okay_here); |
| 7058 } | 7067 } |
| 7059 | 7068 |
| 7060 Label no_info, switch_ready; | 7069 Label no_info, switch_ready; |
| 7061 // Get the elements kind and case on that. | 7070 // Get the elements kind and case on that. |
| 7062 __ cmp(r2, Operand(undefined_sentinel)); | 7071 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
| 7063 __ b(eq, &no_info); | 7072 __ b(eq, &no_info); |
| 7064 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); | 7073 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); |
| 7065 __ JumpIfNotSmi(r3, &no_info); | 7074 |
| 7075 // The type cell may have undefined in its value. |
| 7076 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); |
| 7077 __ b(eq, &no_info); |
| 7078 |
| 7079 // We should have an allocation site object |
| 7080 if (FLAG_debug_code) { |
| 7081 __ push(r3); |
| 7082 __ ldr(r3, FieldMemOperand(r3, 0)); |
| 7083 __ CompareRoot(r3, Heap::kAllocationSiteMapRootIndex); |
| 7084 __ Assert(eq, "Expected AllocationSite object in register edx"); |
| 7085 } |
| 7086 |
| 7087 __ ldr(r3, FieldMemOperand(r3, AllocationSite::kPayloadOffset)); |
| 7066 __ SmiUntag(r3); | 7088 __ SmiUntag(r3); |
| 7067 __ jmp(&switch_ready); | 7089 __ jmp(&switch_ready); |
| 7068 __ bind(&no_info); | 7090 __ bind(&no_info); |
| 7069 __ mov(r3, Operand(GetInitialFastElementsKind())); | 7091 __ mov(r3, Operand(GetInitialFastElementsKind())); |
| 7070 __ bind(&switch_ready); | 7092 __ bind(&switch_ready); |
| 7071 | 7093 |
| 7072 if (argument_count_ == ANY) { | 7094 if (argument_count_ == ANY) { |
| 7073 Label not_zero_case, not_one_case; | 7095 Label not_zero_case, not_one_case; |
| 7074 __ tst(r0, r0); | 7096 __ tst(r0, r0); |
| 7075 __ b(ne, ¬_zero_case); | 7097 __ b(ne, ¬_zero_case); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7177 __ bind(&fast_elements_case); | 7199 __ bind(&fast_elements_case); |
| 7178 GenerateCase(masm, FAST_ELEMENTS); | 7200 GenerateCase(masm, FAST_ELEMENTS); |
| 7179 } | 7201 } |
| 7180 | 7202 |
| 7181 | 7203 |
| 7182 #undef __ | 7204 #undef __ |
| 7183 | 7205 |
| 7184 } } // namespace v8::internal | 7206 } } // namespace v8::internal |
| 7185 | 7207 |
| 7186 #endif // V8_TARGET_ARCH_ARM | 7208 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |