OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 // must always call a backup property check that is complete. | 95 // must always call a backup property check that is complete. |
96 // This function is safe to call if the receiver has fast properties. | 96 // This function is safe to call if the receiver has fast properties. |
97 // Name must be a symbol and receiver must be a heap object. | 97 // Name must be a symbol and receiver must be a heap object. |
98 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 98 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
99 Label* miss_label, | 99 Label* miss_label, |
100 Register receiver, | 100 Register receiver, |
101 String* name, | 101 String* name, |
102 Register scratch0, | 102 Register scratch0, |
103 Register scratch1) { | 103 Register scratch1) { |
104 ASSERT(name->IsSymbol()); | 104 ASSERT(name->IsSymbol()); |
105 __ IncrementCounter(COUNTERS->negative_lookups(), 1, scratch0, scratch1); | 105 Counters* counters = masm->isolate()->counters(); |
106 __ IncrementCounter(COUNTERS->negative_lookups_miss(), 1, scratch0, scratch1); | 106 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); |
| 107 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
107 | 108 |
108 Label done; | 109 Label done; |
109 | 110 |
110 const int kInterceptorOrAccessCheckNeededMask = | 111 const int kInterceptorOrAccessCheckNeededMask = |
111 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 112 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
112 | 113 |
113 // Bail out if the receiver has a named interceptor or requires access checks. | 114 // Bail out if the receiver has a named interceptor or requires access checks. |
114 Register map = scratch1; | 115 Register map = scratch1; |
115 __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 116 __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
116 __ ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); | 117 __ ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 | 193 |
193 // Restore the properties. | 194 // Restore the properties. |
194 __ ldr(properties, | 195 __ ldr(properties, |
195 FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 196 FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
196 } else { | 197 } else { |
197 // Give up probing if still not found the undefined value. | 198 // Give up probing if still not found the undefined value. |
198 __ b(ne, miss_label); | 199 __ b(ne, miss_label); |
199 } | 200 } |
200 } | 201 } |
201 __ bind(&done); | 202 __ bind(&done); |
202 __ DecrementCounter(COUNTERS->negative_lookups_miss(), 1, scratch0, scratch1); | 203 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
203 } | 204 } |
204 | 205 |
205 | 206 |
206 void StubCache::GenerateProbe(MacroAssembler* masm, | 207 void StubCache::GenerateProbe(MacroAssembler* masm, |
207 Code::Flags flags, | 208 Code::Flags flags, |
208 Register receiver, | 209 Register receiver, |
209 Register name, | 210 Register name, |
210 Register scratch, | 211 Register scratch, |
211 Register extra, | 212 Register extra, |
212 Register extra2) { | 213 Register extra2) { |
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 Register scratch2, | 730 Register scratch2, |
730 Register scratch3, | 731 Register scratch3, |
731 JSObject* interceptor_holder, | 732 JSObject* interceptor_holder, |
732 LookupResult* lookup, | 733 LookupResult* lookup, |
733 String* name, | 734 String* name, |
734 const CallOptimization& optimization, | 735 const CallOptimization& optimization, |
735 Label* miss_label) { | 736 Label* miss_label) { |
736 ASSERT(optimization.is_constant_call()); | 737 ASSERT(optimization.is_constant_call()); |
737 ASSERT(!lookup->holder()->IsGlobalObject()); | 738 ASSERT(!lookup->holder()->IsGlobalObject()); |
738 | 739 |
| 740 Counters* counters = masm->isolate()->counters(); |
| 741 |
739 int depth1 = kInvalidProtoDepth; | 742 int depth1 = kInvalidProtoDepth; |
740 int depth2 = kInvalidProtoDepth; | 743 int depth2 = kInvalidProtoDepth; |
741 bool can_do_fast_api_call = false; | 744 bool can_do_fast_api_call = false; |
742 if (optimization.is_simple_api_call() && | 745 if (optimization.is_simple_api_call() && |
743 !lookup->holder()->IsGlobalObject()) { | 746 !lookup->holder()->IsGlobalObject()) { |
744 depth1 = | 747 depth1 = |
745 optimization.GetPrototypeDepthOfExpectedType(object, | 748 optimization.GetPrototypeDepthOfExpectedType(object, |
746 interceptor_holder); | 749 interceptor_holder); |
747 if (depth1 == kInvalidProtoDepth) { | 750 if (depth1 == kInvalidProtoDepth) { |
748 depth2 = | 751 depth2 = |
749 optimization.GetPrototypeDepthOfExpectedType(interceptor_holder, | 752 optimization.GetPrototypeDepthOfExpectedType(interceptor_holder, |
750 lookup->holder()); | 753 lookup->holder()); |
751 } | 754 } |
752 can_do_fast_api_call = (depth1 != kInvalidProtoDepth) || | 755 can_do_fast_api_call = (depth1 != kInvalidProtoDepth) || |
753 (depth2 != kInvalidProtoDepth); | 756 (depth2 != kInvalidProtoDepth); |
754 } | 757 } |
755 | 758 |
756 __ IncrementCounter(COUNTERS->call_const_interceptor(), 1, | 759 __ IncrementCounter(counters->call_const_interceptor(), 1, |
757 scratch1, scratch2); | 760 scratch1, scratch2); |
758 | 761 |
759 if (can_do_fast_api_call) { | 762 if (can_do_fast_api_call) { |
760 __ IncrementCounter(COUNTERS->call_const_interceptor_fast_api(), 1, | 763 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, |
761 scratch1, scratch2); | 764 scratch1, scratch2); |
762 ReserveSpaceForFastApiCall(masm, scratch1); | 765 ReserveSpaceForFastApiCall(masm, scratch1); |
763 } | 766 } |
764 | 767 |
765 // Check that the maps from receiver to interceptor's holder | 768 // Check that the maps from receiver to interceptor's holder |
766 // haven't changed and thus we can invoke interceptor. | 769 // haven't changed and thus we can invoke interceptor. |
767 Label miss_cleanup; | 770 Label miss_cleanup; |
768 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 771 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
769 Register holder = | 772 Register holder = |
770 stub_compiler_->CheckPrototypes(object, receiver, | 773 stub_compiler_->CheckPrototypes(object, receiver, |
(...skipping 1509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2280 } | 2283 } |
2281 | 2284 |
2282 | 2285 |
2283 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2286 MaybeObject* CallStubCompiler::CompileFastApiCall( |
2284 const CallOptimization& optimization, | 2287 const CallOptimization& optimization, |
2285 Object* object, | 2288 Object* object, |
2286 JSObject* holder, | 2289 JSObject* holder, |
2287 JSGlobalPropertyCell* cell, | 2290 JSGlobalPropertyCell* cell, |
2288 JSFunction* function, | 2291 JSFunction* function, |
2289 String* name) { | 2292 String* name) { |
| 2293 Isolate* isolate = masm()->isolate(); |
| 2294 Heap* heap = isolate->heap(); |
| 2295 Counters* counters = isolate->counters(); |
| 2296 |
2290 ASSERT(optimization.is_simple_api_call()); | 2297 ASSERT(optimization.is_simple_api_call()); |
2291 // Bail out if object is a global object as we don't want to | 2298 // Bail out if object is a global object as we don't want to |
2292 // repatch it to global receiver. | 2299 // repatch it to global receiver. |
2293 if (object->IsGlobalObject()) return HEAP->undefined_value(); | 2300 if (object->IsGlobalObject()) return heap->undefined_value(); |
2294 if (cell != NULL) return HEAP->undefined_value(); | 2301 if (cell != NULL) return heap->undefined_value(); |
2295 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2302 int depth = optimization.GetPrototypeDepthOfExpectedType( |
2296 JSObject::cast(object), holder); | 2303 JSObject::cast(object), holder); |
2297 if (depth == kInvalidProtoDepth) return HEAP->undefined_value(); | 2304 if (depth == kInvalidProtoDepth) return heap->undefined_value(); |
2298 | 2305 |
2299 Label miss, miss_before_stack_reserved; | 2306 Label miss, miss_before_stack_reserved; |
2300 | 2307 |
2301 GenerateNameCheck(name, &miss_before_stack_reserved); | 2308 GenerateNameCheck(name, &miss_before_stack_reserved); |
2302 | 2309 |
2303 // Get the receiver from the stack. | 2310 // Get the receiver from the stack. |
2304 const int argc = arguments().immediate(); | 2311 const int argc = arguments().immediate(); |
2305 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2312 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
2306 | 2313 |
2307 // Check that the receiver isn't a smi. | 2314 // Check that the receiver isn't a smi. |
2308 __ tst(r1, Operand(kSmiTagMask)); | 2315 __ tst(r1, Operand(kSmiTagMask)); |
2309 __ b(eq, &miss_before_stack_reserved); | 2316 __ b(eq, &miss_before_stack_reserved); |
2310 | 2317 |
2311 __ IncrementCounter(COUNTERS->call_const(), 1, r0, r3); | 2318 __ IncrementCounter(counters->call_const(), 1, r0, r3); |
2312 __ IncrementCounter(COUNTERS->call_const_fast_api(), 1, r0, r3); | 2319 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); |
2313 | 2320 |
2314 ReserveSpaceForFastApiCall(masm(), r0); | 2321 ReserveSpaceForFastApiCall(masm(), r0); |
2315 | 2322 |
2316 // Check that the maps haven't changed and find a Holder as a side effect. | 2323 // Check that the maps haven't changed and find a Holder as a side effect. |
2317 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2324 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
2318 depth, &miss); | 2325 depth, &miss); |
2319 | 2326 |
2320 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); | 2327 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); |
2321 if (result->IsFailure()) return result; | 2328 if (result->IsFailure()) return result; |
2322 | 2329 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2364 __ b(eq, &miss); | 2371 __ b(eq, &miss); |
2365 } | 2372 } |
2366 | 2373 |
2367 // Make sure that it's okay not to patch the on stack receiver | 2374 // Make sure that it's okay not to patch the on stack receiver |
2368 // unless we're doing a receiver map check. | 2375 // unless we're doing a receiver map check. |
2369 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2376 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
2370 | 2377 |
2371 SharedFunctionInfo* function_info = function->shared(); | 2378 SharedFunctionInfo* function_info = function->shared(); |
2372 switch (check) { | 2379 switch (check) { |
2373 case RECEIVER_MAP_CHECK: | 2380 case RECEIVER_MAP_CHECK: |
2374 __ IncrementCounter(COUNTERS->call_const(), 1, r0, r3); | 2381 __ IncrementCounter(masm()->isolate()->counters()->call_const(), |
| 2382 1, r0, r3); |
2375 | 2383 |
2376 // Check that the maps haven't changed. | 2384 // Check that the maps haven't changed. |
2377 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2385 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
2378 &miss); | 2386 &miss); |
2379 | 2387 |
2380 // Patch the receiver on the stack with the global proxy if | 2388 // Patch the receiver on the stack with the global proxy if |
2381 // necessary. | 2389 // necessary. |
2382 if (object->IsGlobalObject()) { | 2390 if (object->IsGlobalObject()) { |
2383 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2391 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
2384 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 2392 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2551 // necessary. | 2559 // necessary. |
2552 if (object->IsGlobalObject()) { | 2560 if (object->IsGlobalObject()) { |
2553 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | 2561 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); |
2554 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 2562 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
2555 } | 2563 } |
2556 | 2564 |
2557 // Setup the context (function already in r1). | 2565 // Setup the context (function already in r1). |
2558 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 2566 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
2559 | 2567 |
2560 // Jump to the cached code (tail call). | 2568 // Jump to the cached code (tail call). |
2561 __ IncrementCounter(COUNTERS->call_global_inline(), 1, r3, r4); | 2569 Counters* counters = masm()->isolate()->counters(); |
| 2570 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); |
2562 ASSERT(function->is_compiled()); | 2571 ASSERT(function->is_compiled()); |
2563 Handle<Code> code(function->code()); | 2572 Handle<Code> code(function->code()); |
2564 ParameterCount expected(function->shared()->formal_parameter_count()); | 2573 ParameterCount expected(function->shared()->formal_parameter_count()); |
2565 if (V8::UseCrankshaft()) { | 2574 if (V8::UseCrankshaft()) { |
2566 // TODO(kasperl): For now, we always call indirectly through the | 2575 // TODO(kasperl): For now, we always call indirectly through the |
2567 // code field in the function to allow recompilation to take effect | 2576 // code field in the function to allow recompilation to take effect |
2568 // without changing any of the call sites. | 2577 // without changing any of the call sites. |
2569 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 2578 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
2570 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION); | 2579 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION); |
2571 } else { | 2580 } else { |
2572 __ InvokeCode(code, expected, arguments(), | 2581 __ InvokeCode(code, expected, arguments(), |
2573 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 2582 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
2574 } | 2583 } |
2575 | 2584 |
2576 // Handle call cache miss. | 2585 // Handle call cache miss. |
2577 __ bind(&miss); | 2586 __ bind(&miss); |
2578 __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1, r1, r3); | 2587 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); |
2579 MaybeObject* maybe_result = GenerateMissBranch(); | 2588 MaybeObject* maybe_result = GenerateMissBranch(); |
2580 if (maybe_result->IsFailure()) return maybe_result; | 2589 if (maybe_result->IsFailure()) return maybe_result; |
2581 | 2590 |
2582 // Return the generated code. | 2591 // Return the generated code. |
2583 return GetCode(NORMAL, name); | 2592 return GetCode(NORMAL, name); |
2584 } | 2593 } |
2585 | 2594 |
2586 | 2595 |
2587 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2596 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, |
2588 int index, | 2597 int index, |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2734 // global object. We bail out to the runtime system to do that. | 2743 // global object. We bail out to the runtime system to do that. |
2735 __ mov(r4, Operand(Handle<JSGlobalPropertyCell>(cell))); | 2744 __ mov(r4, Operand(Handle<JSGlobalPropertyCell>(cell))); |
2736 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); | 2745 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); |
2737 __ ldr(r6, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); | 2746 __ ldr(r6, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); |
2738 __ cmp(r5, r6); | 2747 __ cmp(r5, r6); |
2739 __ b(eq, &miss); | 2748 __ b(eq, &miss); |
2740 | 2749 |
2741 // Store the value in the cell. | 2750 // Store the value in the cell. |
2742 __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); | 2751 __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); |
2743 | 2752 |
2744 __ IncrementCounter(COUNTERS->named_store_global_inline(), 1, r4, r3); | 2753 Counters* counters = masm()->isolate()->counters(); |
| 2754 __ IncrementCounter(counters->named_store_global_inline(), 1, r4, r3); |
2745 __ Ret(); | 2755 __ Ret(); |
2746 | 2756 |
2747 // Handle store cache miss. | 2757 // Handle store cache miss. |
2748 __ bind(&miss); | 2758 __ bind(&miss); |
2749 __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1, r4, r3); | 2759 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3); |
2750 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2760 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
2751 Builtins::StoreIC_Miss)); | 2761 Builtins::StoreIC_Miss)); |
2752 __ Jump(ic, RelocInfo::CODE_TARGET); | 2762 __ Jump(ic, RelocInfo::CODE_TARGET); |
2753 | 2763 |
2754 // Return the generated code. | 2764 // Return the generated code. |
2755 return GetCode(NORMAL, name); | 2765 return GetCode(NORMAL, name); |
2756 } | 2766 } |
2757 | 2767 |
2758 | 2768 |
2759 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2769 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2923 __ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 2933 __ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); |
2924 | 2934 |
2925 // Check for deleted property if property can actually be deleted. | 2935 // Check for deleted property if property can actually be deleted. |
2926 if (!is_dont_delete) { | 2936 if (!is_dont_delete) { |
2927 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2937 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
2928 __ cmp(r4, ip); | 2938 __ cmp(r4, ip); |
2929 __ b(eq, &miss); | 2939 __ b(eq, &miss); |
2930 } | 2940 } |
2931 | 2941 |
2932 __ mov(r0, r4); | 2942 __ mov(r0, r4); |
2933 __ IncrementCounter(COUNTERS->named_load_global_stub(), 1, r1, r3); | 2943 Counters* counters = masm()->isolate()->counters(); |
| 2944 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); |
2934 __ Ret(); | 2945 __ Ret(); |
2935 | 2946 |
2936 __ bind(&miss); | 2947 __ bind(&miss); |
2937 __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1, r1, r3); | 2948 __ IncrementCounter(counters->named_load_global_stub_miss(), 1, r1, r3); |
2938 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2949 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2939 | 2950 |
2940 // Return the generated code. | 2951 // Return the generated code. |
2941 return GetCode(NORMAL, name); | 2952 return GetCode(NORMAL, name); |
2942 } | 2953 } |
2943 | 2954 |
2944 | 2955 |
2945 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, | 2956 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, |
2946 JSObject* receiver, | 2957 JSObject* receiver, |
2947 JSObject* holder, | 2958 JSObject* holder, |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3072 } | 3083 } |
3073 | 3084 |
3074 | 3085 |
3075 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 3086 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { |
3076 // ----------- S t a t e ------------- | 3087 // ----------- S t a t e ------------- |
3077 // -- lr : return address | 3088 // -- lr : return address |
3078 // -- r0 : key | 3089 // -- r0 : key |
3079 // -- r1 : receiver | 3090 // -- r1 : receiver |
3080 // ----------------------------------- | 3091 // ----------------------------------- |
3081 Label miss; | 3092 Label miss; |
3082 __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1, r2, r3); | 3093 |
| 3094 Counters* counters = masm()->isolate()->counters(); |
| 3095 __ IncrementCounter(counters->keyed_load_string_length(), 1, r2, r3); |
3083 | 3096 |
3084 // Check the key is the cached one. | 3097 // Check the key is the cached one. |
3085 __ cmp(r0, Operand(Handle<String>(name))); | 3098 __ cmp(r0, Operand(Handle<String>(name))); |
3086 __ b(ne, &miss); | 3099 __ b(ne, &miss); |
3087 | 3100 |
3088 GenerateLoadStringLength(masm(), r1, r2, r3, &miss, true); | 3101 GenerateLoadStringLength(masm(), r1, r2, r3, &miss, true); |
3089 __ bind(&miss); | 3102 __ bind(&miss); |
3090 __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1, r2, r3); | 3103 __ DecrementCounter(counters->keyed_load_string_length(), 1, r2, r3); |
3091 | 3104 |
3092 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3105 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3093 | 3106 |
3094 return GetCode(CALLBACKS, name); | 3107 return GetCode(CALLBACKS, name); |
3095 } | 3108 } |
3096 | 3109 |
3097 | 3110 |
3098 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 3111 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { |
3099 // ----------- S t a t e ------------- | 3112 // ----------- S t a t e ------------- |
3100 // -- lr : return address | 3113 // -- lr : return address |
3101 // -- r0 : key | 3114 // -- r0 : key |
3102 // -- r1 : receiver | 3115 // -- r1 : receiver |
3103 // ----------------------------------- | 3116 // ----------------------------------- |
3104 Label miss; | 3117 Label miss; |
3105 | 3118 |
3106 __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1, r2, r3); | 3119 Counters* counters = masm()->isolate()->counters(); |
| 3120 __ IncrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3); |
3107 | 3121 |
3108 // Check the name hasn't changed. | 3122 // Check the name hasn't changed. |
3109 __ cmp(r0, Operand(Handle<String>(name))); | 3123 __ cmp(r0, Operand(Handle<String>(name))); |
3110 __ b(ne, &miss); | 3124 __ b(ne, &miss); |
3111 | 3125 |
3112 GenerateLoadFunctionPrototype(masm(), r1, r2, r3, &miss); | 3126 GenerateLoadFunctionPrototype(masm(), r1, r2, r3, &miss); |
3113 __ bind(&miss); | 3127 __ bind(&miss); |
3114 __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1, r2, r3); | 3128 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3); |
3115 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3129 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3116 | 3130 |
3117 return GetCode(CALLBACKS, name); | 3131 return GetCode(CALLBACKS, name); |
3118 } | 3132 } |
3119 | 3133 |
3120 | 3134 |
3121 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { | 3135 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { |
3122 // ----------- S t a t e ------------- | 3136 // ----------- S t a t e ------------- |
3123 // -- lr : return address | 3137 // -- lr : return address |
3124 // -- r0 : key | 3138 // -- r0 : key |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3172 Map* transition, | 3186 Map* transition, |
3173 String* name) { | 3187 String* name) { |
3174 // ----------- S t a t e ------------- | 3188 // ----------- S t a t e ------------- |
3175 // -- r0 : value | 3189 // -- r0 : value |
3176 // -- r1 : name | 3190 // -- r1 : name |
3177 // -- r2 : receiver | 3191 // -- r2 : receiver |
3178 // -- lr : return address | 3192 // -- lr : return address |
3179 // ----------------------------------- | 3193 // ----------------------------------- |
3180 Label miss; | 3194 Label miss; |
3181 | 3195 |
3182 __ IncrementCounter(COUNTERS->keyed_store_field(), 1, r3, r4); | 3196 Counters* counters = masm()->isolate()->counters(); |
| 3197 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4); |
3183 | 3198 |
3184 // Check that the name has not changed. | 3199 // Check that the name has not changed. |
3185 __ cmp(r1, Operand(Handle<String>(name))); | 3200 __ cmp(r1, Operand(Handle<String>(name))); |
3186 __ b(ne, &miss); | 3201 __ b(ne, &miss); |
3187 | 3202 |
3188 // r3 is used as scratch register. r1 and r2 keep their values if a jump to | 3203 // r3 is used as scratch register. r1 and r2 keep their values if a jump to |
3189 // the miss label is generated. | 3204 // the miss label is generated. |
3190 GenerateStoreField(masm(), | 3205 GenerateStoreField(masm(), |
3191 object, | 3206 object, |
3192 index, | 3207 index, |
3193 transition, | 3208 transition, |
3194 r2, r1, r3, | 3209 r2, r1, r3, |
3195 &miss); | 3210 &miss); |
3196 __ bind(&miss); | 3211 __ bind(&miss); |
3197 | 3212 |
3198 __ DecrementCounter(COUNTERS->keyed_store_field(), 1, r3, r4); | 3213 __ DecrementCounter(counters->keyed_store_field(), 1, r3, r4); |
3199 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 3214 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
3200 Builtins::KeyedStoreIC_Miss)); | 3215 Builtins::KeyedStoreIC_Miss)); |
3201 | 3216 |
3202 __ Jump(ic, RelocInfo::CODE_TARGET); | 3217 __ Jump(ic, RelocInfo::CODE_TARGET); |
3203 | 3218 |
3204 // Return the generated code. | 3219 // Return the generated code. |
3205 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 3220 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
3206 } | 3221 } |
3207 | 3222 |
3208 | 3223 |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3398 // Move argc to r1 and the JSObject to return to r0 and tag it. | 3413 // Move argc to r1 and the JSObject to return to r0 and tag it. |
3399 __ mov(r1, r0); | 3414 __ mov(r1, r0); |
3400 __ mov(r0, r4); | 3415 __ mov(r0, r4); |
3401 __ orr(r0, r0, Operand(kHeapObjectTag)); | 3416 __ orr(r0, r0, Operand(kHeapObjectTag)); |
3402 | 3417 |
3403 // r0: JSObject | 3418 // r0: JSObject |
3404 // r1: argc | 3419 // r1: argc |
3405 // Remove caller arguments and receiver from the stack and return. | 3420 // Remove caller arguments and receiver from the stack and return. |
3406 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2)); | 3421 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2)); |
3407 __ add(sp, sp, Operand(kPointerSize)); | 3422 __ add(sp, sp, Operand(kPointerSize)); |
3408 __ IncrementCounter(COUNTERS->constructed_objects(), 1, r1, r2); | 3423 Counters* counters = masm()->isolate()->counters(); |
3409 __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1, r1, r2); | 3424 __ IncrementCounter(counters->constructed_objects(), 1, r1, r2); |
| 3425 __ IncrementCounter(counters->constructed_objects_stub(), 1, r1, r2); |
3410 __ Jump(lr); | 3426 __ Jump(lr); |
3411 | 3427 |
3412 // Jump to the generic stub in case the specialized code cannot handle the | 3428 // Jump to the generic stub in case the specialized code cannot handle the |
3413 // construction. | 3429 // construction. |
3414 __ bind(&generic_stub_call); | 3430 __ bind(&generic_stub_call); |
3415 Code* code = Isolate::Current()->builtins()->builtin( | 3431 Code* code = Isolate::Current()->builtins()->builtin( |
3416 Builtins::JSConstructStubGeneric); | 3432 Builtins::JSConstructStubGeneric); |
3417 Handle<Code> generic_construct_stub(code); | 3433 Handle<Code> generic_construct_stub(code); |
3418 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 3434 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
3419 | 3435 |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3689 } | 3705 } |
3690 | 3706 |
3691 } else { | 3707 } else { |
3692 // Tag integer as smi and return it. | 3708 // Tag integer as smi and return it. |
3693 __ mov(r0, Operand(value, LSL, kSmiTagSize)); | 3709 __ mov(r0, Operand(value, LSL, kSmiTagSize)); |
3694 __ Ret(); | 3710 __ Ret(); |
3695 } | 3711 } |
3696 | 3712 |
3697 // Slow case, key and receiver still in r0 and r1. | 3713 // Slow case, key and receiver still in r0 and r1. |
3698 __ bind(&slow); | 3714 __ bind(&slow); |
3699 __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1, r2, r3); | 3715 __ IncrementCounter( |
| 3716 masm()->isolate()->counters()->keyed_load_external_array_slow(), |
| 3717 1, r2, r3); |
3700 | 3718 |
3701 // ---------- S t a t e -------------- | 3719 // ---------- S t a t e -------------- |
3702 // -- lr : return address | 3720 // -- lr : return address |
3703 // -- r0 : key | 3721 // -- r0 : key |
3704 // -- r1 : receiver | 3722 // -- r1 : receiver |
3705 // ----------------------------------- | 3723 // ----------------------------------- |
3706 | 3724 |
3707 __ Push(r1, r0); | 3725 __ Push(r1, r0); |
3708 | 3726 |
3709 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 3727 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4017 | 4035 |
4018 return GetCode(flags); | 4036 return GetCode(flags); |
4019 } | 4037 } |
4020 | 4038 |
4021 | 4039 |
4022 #undef __ | 4040 #undef __ |
4023 | 4041 |
4024 } } // namespace v8::internal | 4042 } } // namespace v8::internal |
4025 | 4043 |
4026 #endif // V8_TARGET_ARCH_ARM | 4044 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |