| 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 |