Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 169683003: Second attempt at introducing a premonomorphic state in the call (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 2993 matching lines...) Expand 10 before | Expand all | Expand 10 after
3004 3004
3005 3005
3006 static void GenerateRecordCallTarget(MacroAssembler* masm) { 3006 static void GenerateRecordCallTarget(MacroAssembler* masm) {
3007 // Cache the called function in a feedback vector slot. Cache states 3007 // Cache the called function in a feedback vector slot. Cache states
3008 // are uninitialized, monomorphic (indicated by a JSFunction), and 3008 // are uninitialized, monomorphic (indicated by a JSFunction), and
3009 // megamorphic. 3009 // megamorphic.
3010 // r0 : number of arguments to the construct function 3010 // r0 : number of arguments to the construct function
3011 // r1 : the function to call 3011 // r1 : the function to call
3012 // r2 : Feedback vector 3012 // r2 : Feedback vector
3013 // r3 : slot in feedback vector (Smi) 3013 // r3 : slot in feedback vector (Smi)
3014 Label initialize, done, miss, megamorphic, not_array_function; 3014 Label check_array, initialize_array, initialize_non_array, megamorphic, done;
3015 3015
3016 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), 3016 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
3017 masm->isolate()->heap()->undefined_value()); 3017 masm->isolate()->heap()->undefined_value());
3018 Heap::RootListIndex kMegamorphicRootIndex = Heap::kUndefinedValueRootIndex;
3018 ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()), 3019 ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()),
3019 masm->isolate()->heap()->the_hole_value()); 3020 masm->isolate()->heap()->the_hole_value());
3021 Heap::RootListIndex kUninitializedRootIndex = Heap::kTheHoleValueRootIndex;
3022 ASSERT_EQ(*TypeFeedbackInfo::PremonomorphicSentinel(masm->isolate()),
3023 masm->isolate()->heap()->null_value());
3024 Heap::RootListIndex kPremonomorphicRootIndex = Heap::kNullValueRootIndex;
3020 3025
3021 // Load the cache state into r4. 3026 // Load the cache state into r4.
3022 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); 3027 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3023 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); 3028 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
3024 3029
3025 // A monomorphic cache hit or an already megamorphic state: invoke the 3030 // A monomorphic cache hit or an already megamorphic state: invoke the
3026 // function without changing the state. 3031 // function without changing the state.
3027 __ cmp(r4, r1); 3032 __ cmp(r4, r1);
3028 __ b(eq, &done); 3033 __ b(eq, &done);
3034 __ CompareRoot(r4, kMegamorphicRootIndex);
3035 __ b(eq, &done);
3029 3036
3030 // If we came here, we need to see if we are the array function. 3037 // Check if we're dealing with the Array function or not.
3031 // If we didn't have a matching function, and we didn't find the megamorph 3038 __ LoadArrayFunction(r5);
3032 // sentinel, then we have in the slot either some other function or an 3039 __ cmp(r1, r5);
3033 // AllocationSite. Do a map check on the object in ecx. 3040 __ b(eq, &check_array);
3034 __ ldr(r5, FieldMemOperand(r4, 0));
3035 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
3036 __ b(ne, &miss);
3037 3041
3038 // Make sure the function is the Array() function 3042 // Non-array cache: Check the cache state.
3039 __ LoadArrayFunction(r4); 3043 __ CompareRoot(r4, kPremonomorphicRootIndex);
3040 __ cmp(r1, r4); 3044 __ b(eq, &initialize_non_array);
3045 __ CompareRoot(r4, kUninitializedRootIndex);
3041 __ b(ne, &megamorphic); 3046 __ b(ne, &megamorphic);
3042 __ jmp(&done);
3043 3047
3044 __ bind(&miss); 3048 // Non-array cache: Uninitialized -> premonomorphic. The sentinel is an
3045 3049 // immortal immovable object (null) so no write-barrier is needed.
3046 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
3047 // megamorphic.
3048 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
3049 __ b(eq, &initialize);
3050 // MegamorphicSentinel is an immortal immovable object (undefined) so no
3051 // write-barrier is needed.
3052 __ bind(&megamorphic);
3053 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); 3050 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3054 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 3051 __ LoadRoot(ip, kPremonomorphicRootIndex);
3055 __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize)); 3052 __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
3056 __ jmp(&done); 3053 __ jmp(&done);
3057 3054
3058 // An uninitialized cache is patched with the function or sentinel to 3055 // Array cache: Check the cache state to see if we're in a monomorphic
3059 // indicate the ElementsKind if function is the Array constructor. 3056 // state where the state object is an AllocationSite object.
3060 __ bind(&initialize); 3057 __ bind(&check_array);
3061 // Make sure the function is the Array() function 3058 __ ldr(r5, FieldMemOperand(r4, 0));
3062 __ LoadArrayFunction(r4); 3059 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
3063 __ cmp(r1, r4); 3060 __ b(eq, &done);
3064 __ b(ne, &not_array_function);
3065 3061
3066 // The target function is the Array constructor, 3062 // Array cache: Uninitialized or premonomorphic -> monomorphic.
3067 // Create an AllocationSite if we don't already have it, store it in the slot. 3063 __ CompareRoot(r4, kUninitializedRootIndex);
3064 __ b(eq, &initialize_array);
3065 __ CompareRoot(r4, kPremonomorphicRootIndex);
3066 __ b(eq, &initialize_array);
3067
3068 // Both caches: Monomorphic -> megamorphic. The sentinel is an
3069 // immortal immovable object (undefined) so no write-barrier is needed.
3070 __ bind(&megamorphic);
3071 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3072 __ LoadRoot(ip, kMegamorphicRootIndex);
3073 __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
3074 __ jmp(&done);
3075
3076 // Array cache: Uninitialized or premonomorphic -> monomorphic.
3077 __ bind(&initialize_array);
3068 { 3078 {
3069 FrameScope scope(masm, StackFrame::INTERNAL); 3079 FrameScope scope(masm, StackFrame::INTERNAL);
3070 3080
3071 // Arguments register must be smi-tagged to call out. 3081 // Arguments register must be smi-tagged to call out.
3072 __ SmiTag(r0); 3082 __ SmiTag(r0);
3073 __ Push(r3, r2, r1, r0); 3083 __ Push(r3, r2, r1, r0);
3074 3084
3075 CreateAllocationSiteStub create_stub; 3085 CreateAllocationSiteStub create_stub;
3076 __ CallStub(&create_stub); 3086 __ CallStub(&create_stub);
3077 3087
3078 __ Pop(r3, r2, r1, r0); 3088 __ Pop(r3, r2, r1, r0);
3079 __ SmiUntag(r0); 3089 __ SmiUntag(r0);
3080 } 3090 }
3081 __ b(&done); 3091 __ b(&done);
3082 3092
3083 __ bind(&not_array_function); 3093 // Non-array cache: Premonomorphic -> monomorphic.
3084 3094 __ bind(&initialize_non_array);
3085 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); 3095 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3086 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 3096 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3087 __ str(r1, MemOperand(r4, 0)); 3097 __ str(r1, MemOperand(r4, 0));
3088 3098
3089 __ Push(r4, r2, r1); 3099 __ Push(r4, r2, r1);
3090 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs, 3100 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs,
3091 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 3101 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
3092 __ Pop(r4, r2, r1); 3102 __ Pop(r4, r2, r1);
3093 3103
3094 __ bind(&done); 3104 __ bind(&done);
(...skipping 2484 matching lines...) Expand 10 before | Expand all | Expand 10 after
5579 MemOperand(fp, 6 * kPointerSize), 5589 MemOperand(fp, 6 * kPointerSize),
5580 NULL); 5590 NULL);
5581 } 5591 }
5582 5592
5583 5593
5584 #undef __ 5594 #undef __
5585 5595
5586 } } // namespace v8::internal 5596 } } // namespace v8::internal
5587 5597
5588 #endif // V8_TARGET_ARCH_ARM 5598 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/a64/code-stubs-a64.cc ('k') | src/ia32/code-stubs-ia32.cc » ('j') | src/runtime.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698