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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 // must always call a backup property check that is complete. | 107 // must always call a backup property check that is complete. |
108 // This function is safe to call if the receiver has fast properties. | 108 // This function is safe to call if the receiver has fast properties. |
109 // Name must be a symbol and receiver must be a heap object. | 109 // Name must be a symbol and receiver must be a heap object. |
110 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 110 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
111 Label* miss_label, | 111 Label* miss_label, |
112 Register receiver, | 112 Register receiver, |
113 String* name, | 113 String* name, |
114 Register r0, | 114 Register r0, |
115 Register r1) { | 115 Register r1) { |
116 ASSERT(name->IsSymbol()); | 116 ASSERT(name->IsSymbol()); |
117 __ IncrementCounter(COUNTERS->negative_lookups(), 1); | 117 Counters* counters = masm->isolate()->counters(); |
118 __ IncrementCounter(COUNTERS->negative_lookups_miss(), 1); | 118 __ IncrementCounter(counters->negative_lookups(), 1); |
| 119 __ IncrementCounter(counters->negative_lookups_miss(), 1); |
119 | 120 |
120 Label done; | 121 Label done; |
121 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 122 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); |
122 | 123 |
123 const int kInterceptorOrAccessCheckNeededMask = | 124 const int kInterceptorOrAccessCheckNeededMask = |
124 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 125 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
125 | 126 |
126 // Bail out if the receiver has a named interceptor or requires access checks. | 127 // Bail out if the receiver has a named interceptor or requires access checks. |
127 __ test_b(FieldOperand(r0, Map::kBitFieldOffset), | 128 __ test_b(FieldOperand(r0, Map::kBitFieldOffset), |
128 kInterceptorOrAccessCheckNeededMask); | 129 kInterceptorOrAccessCheckNeededMask); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset), | 192 __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset), |
192 kIsSymbolMask); | 193 kIsSymbolMask); |
193 __ j(zero, miss_label, not_taken); | 194 __ j(zero, miss_label, not_taken); |
194 } else { | 195 } else { |
195 // Give up probing if still not found the undefined value. | 196 // Give up probing if still not found the undefined value. |
196 __ j(not_equal, miss_label, not_taken); | 197 __ j(not_equal, miss_label, not_taken); |
197 } | 198 } |
198 } | 199 } |
199 | 200 |
200 __ bind(&done); | 201 __ bind(&done); |
201 __ DecrementCounter(COUNTERS->negative_lookups_miss(), 1); | 202 __ DecrementCounter(counters->negative_lookups_miss(), 1); |
202 } | 203 } |
203 | 204 |
204 | 205 |
205 void StubCache::GenerateProbe(MacroAssembler* masm, | 206 void StubCache::GenerateProbe(MacroAssembler* masm, |
206 Code::Flags flags, | 207 Code::Flags flags, |
207 Register receiver, | 208 Register receiver, |
208 Register name, | 209 Register name, |
209 Register scratch, | 210 Register scratch, |
210 Register extra, | 211 Register extra, |
211 Register extra2) { | 212 Register extra2) { |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 interceptor_holder); | 608 interceptor_holder); |
608 if (depth1 == kInvalidProtoDepth) { | 609 if (depth1 == kInvalidProtoDepth) { |
609 depth2 = | 610 depth2 = |
610 optimization.GetPrototypeDepthOfExpectedType(interceptor_holder, | 611 optimization.GetPrototypeDepthOfExpectedType(interceptor_holder, |
611 lookup->holder()); | 612 lookup->holder()); |
612 } | 613 } |
613 can_do_fast_api_call = (depth1 != kInvalidProtoDepth) || | 614 can_do_fast_api_call = (depth1 != kInvalidProtoDepth) || |
614 (depth2 != kInvalidProtoDepth); | 615 (depth2 != kInvalidProtoDepth); |
615 } | 616 } |
616 | 617 |
617 __ IncrementCounter(COUNTERS->call_const_interceptor(), 1); | 618 Counters* counters = masm->isolate()->counters(); |
| 619 __ IncrementCounter(counters->call_const_interceptor(), 1); |
618 | 620 |
619 if (can_do_fast_api_call) { | 621 if (can_do_fast_api_call) { |
620 __ IncrementCounter(COUNTERS->call_const_interceptor_fast_api(), 1); | 622 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1); |
621 ReserveSpaceForFastApiCall(masm, scratch1); | 623 ReserveSpaceForFastApiCall(masm, scratch1); |
622 } | 624 } |
623 | 625 |
624 // Check that the maps from receiver to interceptor's holder | 626 // Check that the maps from receiver to interceptor's holder |
625 // haven't changed and thus we can invoke interceptor. | 627 // haven't changed and thus we can invoke interceptor. |
626 Label miss_cleanup; | 628 Label miss_cleanup; |
627 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 629 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
628 Register holder = | 630 Register holder = |
629 stub_compiler_->CheckPrototypes(object, receiver, | 631 stub_compiler_->CheckPrototypes(object, receiver, |
630 interceptor_holder, scratch1, | 632 interceptor_holder, scratch1, |
(...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2148 GenerateNameCheck(name, &miss_before_stack_reserved); | 2150 GenerateNameCheck(name, &miss_before_stack_reserved); |
2149 | 2151 |
2150 // Get the receiver from the stack. | 2152 // Get the receiver from the stack. |
2151 const int argc = arguments().immediate(); | 2153 const int argc = arguments().immediate(); |
2152 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2154 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
2153 | 2155 |
2154 // Check that the receiver isn't a smi. | 2156 // Check that the receiver isn't a smi. |
2155 __ test(edx, Immediate(kSmiTagMask)); | 2157 __ test(edx, Immediate(kSmiTagMask)); |
2156 __ j(zero, &miss_before_stack_reserved, not_taken); | 2158 __ j(zero, &miss_before_stack_reserved, not_taken); |
2157 | 2159 |
2158 __ IncrementCounter(COUNTERS->call_const(), 1); | 2160 Counters* counters = masm()->isolate()->counters(); |
2159 __ IncrementCounter(COUNTERS->call_const_fast_api(), 1); | 2161 __ IncrementCounter(counters->call_const(), 1); |
| 2162 __ IncrementCounter(counters->call_const_fast_api(), 1); |
2160 | 2163 |
2161 // Allocate space for v8::Arguments implicit values. Must be initialized | 2164 // Allocate space for v8::Arguments implicit values. Must be initialized |
2162 // before calling any runtime function. | 2165 // before calling any runtime function. |
2163 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); | 2166 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); |
2164 | 2167 |
2165 // Check that the maps haven't changed and find a Holder as a side effect. | 2168 // Check that the maps haven't changed and find a Holder as a side effect. |
2166 CheckPrototypes(JSObject::cast(object), edx, holder, | 2169 CheckPrototypes(JSObject::cast(object), edx, holder, |
2167 ebx, eax, edi, name, depth, &miss); | 2170 ebx, eax, edi, name, depth, &miss); |
2168 | 2171 |
2169 // Move the return address on top of the stack. | 2172 // Move the return address on top of the stack. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2223 __ j(zero, &miss, not_taken); | 2226 __ j(zero, &miss, not_taken); |
2224 } | 2227 } |
2225 | 2228 |
2226 // Make sure that it's okay not to patch the on stack receiver | 2229 // Make sure that it's okay not to patch the on stack receiver |
2227 // unless we're doing a receiver map check. | 2230 // unless we're doing a receiver map check. |
2228 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2231 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
2229 | 2232 |
2230 SharedFunctionInfo* function_info = function->shared(); | 2233 SharedFunctionInfo* function_info = function->shared(); |
2231 switch (check) { | 2234 switch (check) { |
2232 case RECEIVER_MAP_CHECK: | 2235 case RECEIVER_MAP_CHECK: |
2233 __ IncrementCounter(COUNTERS->call_const(), 1); | 2236 __ IncrementCounter(masm()->isolate()->counters()->call_const(), 1); |
2234 | 2237 |
2235 // Check that the maps haven't changed. | 2238 // Check that the maps haven't changed. |
2236 CheckPrototypes(JSObject::cast(object), edx, holder, | 2239 CheckPrototypes(JSObject::cast(object), edx, holder, |
2237 ebx, eax, edi, name, &miss); | 2240 ebx, eax, edi, name, &miss); |
2238 | 2241 |
2239 // Patch the receiver on the stack with the global proxy if | 2242 // Patch the receiver on the stack with the global proxy if |
2240 // necessary. | 2243 // necessary. |
2241 if (object->IsGlobalObject()) { | 2244 if (object->IsGlobalObject()) { |
2242 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2245 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
2243 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2246 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2423 // Patch the receiver on the stack with the global proxy. | 2426 // Patch the receiver on the stack with the global proxy. |
2424 if (object->IsGlobalObject()) { | 2427 if (object->IsGlobalObject()) { |
2425 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2428 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
2426 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2429 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
2427 } | 2430 } |
2428 | 2431 |
2429 // Setup the context (function already in edi). | 2432 // Setup the context (function already in edi). |
2430 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 2433 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
2431 | 2434 |
2432 // Jump to the cached code (tail call). | 2435 // Jump to the cached code (tail call). |
2433 __ IncrementCounter(COUNTERS->call_global_inline(), 1); | 2436 Counters* counters = masm()->isolate()->counters(); |
| 2437 __ IncrementCounter(counters->call_global_inline(), 1); |
2434 ASSERT(function->is_compiled()); | 2438 ASSERT(function->is_compiled()); |
2435 ParameterCount expected(function->shared()->formal_parameter_count()); | 2439 ParameterCount expected(function->shared()->formal_parameter_count()); |
2436 if (V8::UseCrankshaft()) { | 2440 if (V8::UseCrankshaft()) { |
2437 // TODO(kasperl): For now, we always call indirectly through the | 2441 // TODO(kasperl): For now, we always call indirectly through the |
2438 // code field in the function to allow recompilation to take effect | 2442 // code field in the function to allow recompilation to take effect |
2439 // without changing any of the call sites. | 2443 // without changing any of the call sites. |
2440 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), | 2444 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), |
2441 expected, arguments(), JUMP_FUNCTION); | 2445 expected, arguments(), JUMP_FUNCTION); |
2442 } else { | 2446 } else { |
2443 Handle<Code> code(function->code()); | 2447 Handle<Code> code(function->code()); |
2444 __ InvokeCode(code, expected, arguments(), | 2448 __ InvokeCode(code, expected, arguments(), |
2445 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 2449 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
2446 } | 2450 } |
2447 | 2451 |
2448 // Handle call cache miss. | 2452 // Handle call cache miss. |
2449 __ bind(&miss); | 2453 __ bind(&miss); |
2450 __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1); | 2454 __ IncrementCounter(counters->call_global_inline_miss(), 1); |
2451 MaybeObject* maybe_result = GenerateMissBranch(); | 2455 MaybeObject* maybe_result = GenerateMissBranch(); |
2452 if (maybe_result->IsFailure()) return maybe_result; | 2456 if (maybe_result->IsFailure()) return maybe_result; |
2453 | 2457 |
2454 // Return the generated code. | 2458 // Return the generated code. |
2455 return GetCode(NORMAL, name); | 2459 return GetCode(NORMAL, name); |
2456 } | 2460 } |
2457 | 2461 |
2458 | 2462 |
2459 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2463 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, |
2460 int index, | 2464 int index, |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2619 // cell could have been deleted and reintroducing the global needs | 2623 // cell could have been deleted and reintroducing the global needs |
2620 // to update the property details in the property dictionary of the | 2624 // to update the property details in the property dictionary of the |
2621 // global object. We bail out to the runtime system to do that. | 2625 // global object. We bail out to the runtime system to do that. |
2622 __ cmp(cell_operand, FACTORY->the_hole_value()); | 2626 __ cmp(cell_operand, FACTORY->the_hole_value()); |
2623 __ j(equal, &miss); | 2627 __ j(equal, &miss); |
2624 | 2628 |
2625 // Store the value in the cell. | 2629 // Store the value in the cell. |
2626 __ mov(cell_operand, eax); | 2630 __ mov(cell_operand, eax); |
2627 | 2631 |
2628 // Return the value (register eax). | 2632 // Return the value (register eax). |
2629 __ IncrementCounter(COUNTERS->named_store_global_inline(), 1); | 2633 Counters* counters = masm()->isolate()->counters(); |
| 2634 __ IncrementCounter(counters->named_store_global_inline(), 1); |
2630 __ ret(0); | 2635 __ ret(0); |
2631 | 2636 |
2632 // Handle store cache miss. | 2637 // Handle store cache miss. |
2633 __ bind(&miss); | 2638 __ bind(&miss); |
2634 __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1); | 2639 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); |
2635 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2640 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
2636 Builtins::StoreIC_Miss)); | 2641 Builtins::StoreIC_Miss)); |
2637 __ jmp(ic, RelocInfo::CODE_TARGET); | 2642 __ jmp(ic, RelocInfo::CODE_TARGET); |
2638 | 2643 |
2639 // Return the generated code. | 2644 // Return the generated code. |
2640 return GetCode(NORMAL, name); | 2645 return GetCode(NORMAL, name); |
2641 } | 2646 } |
2642 | 2647 |
2643 | 2648 |
2644 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 2649 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, |
2645 int index, | 2650 int index, |
2646 Map* transition, | 2651 Map* transition, |
2647 String* name) { | 2652 String* name) { |
2648 // ----------- S t a t e ------------- | 2653 // ----------- S t a t e ------------- |
2649 // -- eax : value | 2654 // -- eax : value |
2650 // -- ecx : key | 2655 // -- ecx : key |
2651 // -- edx : receiver | 2656 // -- edx : receiver |
2652 // -- esp[0] : return address | 2657 // -- esp[0] : return address |
2653 // ----------------------------------- | 2658 // ----------------------------------- |
2654 Label miss; | 2659 Label miss; |
2655 | 2660 |
2656 __ IncrementCounter(COUNTERS->keyed_store_field(), 1); | 2661 Counters* counters = masm()->isolate()->counters(); |
| 2662 __ IncrementCounter(counters->keyed_store_field(), 1); |
2657 | 2663 |
2658 // Check that the name has not changed. | 2664 // Check that the name has not changed. |
2659 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); | 2665 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); |
2660 __ j(not_equal, &miss, not_taken); | 2666 __ j(not_equal, &miss, not_taken); |
2661 | 2667 |
2662 // Generate store field code. Trashes the name register. | 2668 // Generate store field code. Trashes the name register. |
2663 GenerateStoreField(masm(), | 2669 GenerateStoreField(masm(), |
2664 object, | 2670 object, |
2665 index, | 2671 index, |
2666 transition, | 2672 transition, |
2667 edx, ecx, ebx, | 2673 edx, ecx, ebx, |
2668 &miss); | 2674 &miss); |
2669 | 2675 |
2670 // Handle store cache miss. | 2676 // Handle store cache miss. |
2671 __ bind(&miss); | 2677 __ bind(&miss); |
2672 __ DecrementCounter(COUNTERS->keyed_store_field(), 1); | 2678 __ DecrementCounter(counters->keyed_store_field(), 1); |
2673 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2679 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
2674 Builtins::KeyedStoreIC_Miss)); | 2680 Builtins::KeyedStoreIC_Miss)); |
2675 __ jmp(ic, RelocInfo::CODE_TARGET); | 2681 __ jmp(ic, RelocInfo::CODE_TARGET); |
2676 | 2682 |
2677 // Return the generated code. | 2683 // Return the generated code. |
2678 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2684 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
2679 } | 2685 } |
2680 | 2686 |
2681 | 2687 |
2682 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( | 2688 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2918 | 2924 |
2919 // Check for deleted property if property can actually be deleted. | 2925 // Check for deleted property if property can actually be deleted. |
2920 if (!is_dont_delete) { | 2926 if (!is_dont_delete) { |
2921 __ cmp(ebx, FACTORY->the_hole_value()); | 2927 __ cmp(ebx, FACTORY->the_hole_value()); |
2922 __ j(equal, &miss, not_taken); | 2928 __ j(equal, &miss, not_taken); |
2923 } else if (FLAG_debug_code) { | 2929 } else if (FLAG_debug_code) { |
2924 __ cmp(ebx, FACTORY->the_hole_value()); | 2930 __ cmp(ebx, FACTORY->the_hole_value()); |
2925 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 2931 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
2926 } | 2932 } |
2927 | 2933 |
2928 __ IncrementCounter(COUNTERS->named_load_global_stub(), 1); | 2934 Counters* counters = masm()->isolate()->counters(); |
| 2935 __ IncrementCounter(counters->named_load_global_stub(), 1); |
2929 __ mov(eax, ebx); | 2936 __ mov(eax, ebx); |
2930 __ ret(0); | 2937 __ ret(0); |
2931 | 2938 |
2932 __ bind(&miss); | 2939 __ bind(&miss); |
2933 __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1); | 2940 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); |
2934 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2941 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2935 | 2942 |
2936 // Return the generated code. | 2943 // Return the generated code. |
2937 return GetCode(NORMAL, name); | 2944 return GetCode(NORMAL, name); |
2938 } | 2945 } |
2939 | 2946 |
2940 | 2947 |
2941 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, | 2948 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, |
2942 JSObject* receiver, | 2949 JSObject* receiver, |
2943 JSObject* holder, | 2950 JSObject* holder, |
2944 int index) { | 2951 int index) { |
2945 // ----------- S t a t e ------------- | 2952 // ----------- S t a t e ------------- |
2946 // -- eax : key | 2953 // -- eax : key |
2947 // -- edx : receiver | 2954 // -- edx : receiver |
2948 // -- esp[0] : return address | 2955 // -- esp[0] : return address |
2949 // ----------------------------------- | 2956 // ----------------------------------- |
2950 Label miss; | 2957 Label miss; |
2951 | 2958 |
2952 __ IncrementCounter(COUNTERS->keyed_load_field(), 1); | 2959 Counters* counters = masm()->isolate()->counters(); |
| 2960 __ IncrementCounter(counters->keyed_load_field(), 1); |
2953 | 2961 |
2954 // Check that the name has not changed. | 2962 // Check that the name has not changed. |
2955 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 2963 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
2956 __ j(not_equal, &miss, not_taken); | 2964 __ j(not_equal, &miss, not_taken); |
2957 | 2965 |
2958 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); | 2966 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); |
2959 | 2967 |
2960 __ bind(&miss); | 2968 __ bind(&miss); |
2961 __ DecrementCounter(COUNTERS->keyed_load_field(), 1); | 2969 __ DecrementCounter(counters->keyed_load_field(), 1); |
2962 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2970 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2963 | 2971 |
2964 // Return the generated code. | 2972 // Return the generated code. |
2965 return GetCode(FIELD, name); | 2973 return GetCode(FIELD, name); |
2966 } | 2974 } |
2967 | 2975 |
2968 | 2976 |
2969 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( | 2977 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( |
2970 String* name, | 2978 String* name, |
2971 JSObject* receiver, | 2979 JSObject* receiver, |
2972 JSObject* holder, | 2980 JSObject* holder, |
2973 AccessorInfo* callback) { | 2981 AccessorInfo* callback) { |
2974 // ----------- S t a t e ------------- | 2982 // ----------- S t a t e ------------- |
2975 // -- eax : key | 2983 // -- eax : key |
2976 // -- edx : receiver | 2984 // -- edx : receiver |
2977 // -- esp[0] : return address | 2985 // -- esp[0] : return address |
2978 // ----------------------------------- | 2986 // ----------------------------------- |
2979 Label miss; | 2987 Label miss; |
2980 | 2988 |
2981 __ IncrementCounter(COUNTERS->keyed_load_callback(), 1); | 2989 Counters* counters = masm()->isolate()->counters(); |
| 2990 __ IncrementCounter(counters->keyed_load_callback(), 1); |
2982 | 2991 |
2983 // Check that the name has not changed. | 2992 // Check that the name has not changed. |
2984 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 2993 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
2985 __ j(not_equal, &miss, not_taken); | 2994 __ j(not_equal, &miss, not_taken); |
2986 | 2995 |
2987 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx, | 2996 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx, |
2988 ecx, edi, callback, name, &miss); | 2997 ecx, edi, callback, name, &miss); |
2989 if (result->IsFailure()) { | 2998 if (result->IsFailure()) { |
2990 miss.Unuse(); | 2999 miss.Unuse(); |
2991 return result; | 3000 return result; |
2992 } | 3001 } |
2993 | 3002 |
2994 __ bind(&miss); | 3003 __ bind(&miss); |
2995 | 3004 |
2996 __ DecrementCounter(COUNTERS->keyed_load_callback(), 1); | 3005 __ DecrementCounter(counters->keyed_load_callback(), 1); |
2997 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3006 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2998 | 3007 |
2999 // Return the generated code. | 3008 // Return the generated code. |
3000 return GetCode(CALLBACKS, name); | 3009 return GetCode(CALLBACKS, name); |
3001 } | 3010 } |
3002 | 3011 |
3003 | 3012 |
3004 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 3013 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, |
3005 JSObject* receiver, | 3014 JSObject* receiver, |
3006 JSObject* holder, | 3015 JSObject* holder, |
3007 Object* value) { | 3016 Object* value) { |
3008 // ----------- S t a t e ------------- | 3017 // ----------- S t a t e ------------- |
3009 // -- eax : key | 3018 // -- eax : key |
3010 // -- edx : receiver | 3019 // -- edx : receiver |
3011 // -- esp[0] : return address | 3020 // -- esp[0] : return address |
3012 // ----------------------------------- | 3021 // ----------------------------------- |
3013 Label miss; | 3022 Label miss; |
3014 | 3023 |
3015 __ IncrementCounter(COUNTERS->keyed_load_constant_function(), 1); | 3024 Counters* counters = masm()->isolate()->counters(); |
| 3025 __ IncrementCounter(counters->keyed_load_constant_function(), 1); |
3016 | 3026 |
3017 // Check that the name has not changed. | 3027 // Check that the name has not changed. |
3018 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 3028 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
3019 __ j(not_equal, &miss, not_taken); | 3029 __ j(not_equal, &miss, not_taken); |
3020 | 3030 |
3021 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, | 3031 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, |
3022 value, name, &miss); | 3032 value, name, &miss); |
3023 __ bind(&miss); | 3033 __ bind(&miss); |
3024 __ DecrementCounter(COUNTERS->keyed_load_constant_function(), 1); | 3034 __ DecrementCounter(counters->keyed_load_constant_function(), 1); |
3025 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3035 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3026 | 3036 |
3027 // Return the generated code. | 3037 // Return the generated code. |
3028 return GetCode(CONSTANT_FUNCTION, name); | 3038 return GetCode(CONSTANT_FUNCTION, name); |
3029 } | 3039 } |
3030 | 3040 |
3031 | 3041 |
3032 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 3042 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
3033 JSObject* holder, | 3043 JSObject* holder, |
3034 String* name) { | 3044 String* name) { |
3035 // ----------- S t a t e ------------- | 3045 // ----------- S t a t e ------------- |
3036 // -- eax : key | 3046 // -- eax : key |
3037 // -- edx : receiver | 3047 // -- edx : receiver |
3038 // -- esp[0] : return address | 3048 // -- esp[0] : return address |
3039 // ----------------------------------- | 3049 // ----------------------------------- |
3040 Label miss; | 3050 Label miss; |
3041 | 3051 |
3042 __ IncrementCounter(COUNTERS->keyed_load_interceptor(), 1); | 3052 Counters* counters = masm()->isolate()->counters(); |
| 3053 __ IncrementCounter(counters->keyed_load_interceptor(), 1); |
3043 | 3054 |
3044 // Check that the name has not changed. | 3055 // Check that the name has not changed. |
3045 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 3056 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
3046 __ j(not_equal, &miss, not_taken); | 3057 __ j(not_equal, &miss, not_taken); |
3047 | 3058 |
3048 LookupResult lookup; | 3059 LookupResult lookup; |
3049 LookupPostInterceptor(holder, name, &lookup); | 3060 LookupPostInterceptor(holder, name, &lookup); |
3050 GenerateLoadInterceptor(receiver, | 3061 GenerateLoadInterceptor(receiver, |
3051 holder, | 3062 holder, |
3052 &lookup, | 3063 &lookup, |
3053 edx, | 3064 edx, |
3054 eax, | 3065 eax, |
3055 ecx, | 3066 ecx, |
3056 ebx, | 3067 ebx, |
3057 edi, | 3068 edi, |
3058 name, | 3069 name, |
3059 &miss); | 3070 &miss); |
3060 __ bind(&miss); | 3071 __ bind(&miss); |
3061 __ DecrementCounter(COUNTERS->keyed_load_interceptor(), 1); | 3072 __ DecrementCounter(counters->keyed_load_interceptor(), 1); |
3062 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3073 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3063 | 3074 |
3064 // Return the generated code. | 3075 // Return the generated code. |
3065 return GetCode(INTERCEPTOR, name); | 3076 return GetCode(INTERCEPTOR, name); |
3066 } | 3077 } |
3067 | 3078 |
3068 | 3079 |
3069 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 3080 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { |
3070 // ----------- S t a t e ------------- | 3081 // ----------- S t a t e ------------- |
3071 // -- eax : key | 3082 // -- eax : key |
3072 // -- edx : receiver | 3083 // -- edx : receiver |
3073 // -- esp[0] : return address | 3084 // -- esp[0] : return address |
3074 // ----------------------------------- | 3085 // ----------------------------------- |
3075 Label miss; | 3086 Label miss; |
3076 | 3087 |
3077 __ IncrementCounter(COUNTERS->keyed_load_array_length(), 1); | 3088 Counters* counters = masm()->isolate()->counters(); |
| 3089 __ IncrementCounter(counters->keyed_load_array_length(), 1); |
3078 | 3090 |
3079 // Check that the name has not changed. | 3091 // Check that the name has not changed. |
3080 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 3092 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
3081 __ j(not_equal, &miss, not_taken); | 3093 __ j(not_equal, &miss, not_taken); |
3082 | 3094 |
3083 GenerateLoadArrayLength(masm(), edx, ecx, &miss); | 3095 GenerateLoadArrayLength(masm(), edx, ecx, &miss); |
3084 __ bind(&miss); | 3096 __ bind(&miss); |
3085 __ DecrementCounter(COUNTERS->keyed_load_array_length(), 1); | 3097 __ DecrementCounter(counters->keyed_load_array_length(), 1); |
3086 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3098 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3087 | 3099 |
3088 // Return the generated code. | 3100 // Return the generated code. |
3089 return GetCode(CALLBACKS, name); | 3101 return GetCode(CALLBACKS, name); |
3090 } | 3102 } |
3091 | 3103 |
3092 | 3104 |
3093 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 3105 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { |
3094 // ----------- S t a t e ------------- | 3106 // ----------- S t a t e ------------- |
3095 // -- eax : key | 3107 // -- eax : key |
3096 // -- edx : receiver | 3108 // -- edx : receiver |
3097 // -- esp[0] : return address | 3109 // -- esp[0] : return address |
3098 // ----------------------------------- | 3110 // ----------------------------------- |
3099 Label miss; | 3111 Label miss; |
3100 | 3112 |
3101 __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1); | 3113 Counters* counters = masm()->isolate()->counters(); |
| 3114 __ IncrementCounter(counters->keyed_load_string_length(), 1); |
3102 | 3115 |
3103 // Check that the name has not changed. | 3116 // Check that the name has not changed. |
3104 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 3117 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
3105 __ j(not_equal, &miss, not_taken); | 3118 __ j(not_equal, &miss, not_taken); |
3106 | 3119 |
3107 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); | 3120 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); |
3108 __ bind(&miss); | 3121 __ bind(&miss); |
3109 __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1); | 3122 __ DecrementCounter(counters->keyed_load_string_length(), 1); |
3110 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3123 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3111 | 3124 |
3112 // Return the generated code. | 3125 // Return the generated code. |
3113 return GetCode(CALLBACKS, name); | 3126 return GetCode(CALLBACKS, name); |
3114 } | 3127 } |
3115 | 3128 |
3116 | 3129 |
3117 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 3130 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { |
3118 // ----------- S t a t e ------------- | 3131 // ----------- S t a t e ------------- |
3119 // -- eax : key | 3132 // -- eax : key |
3120 // -- edx : receiver | 3133 // -- edx : receiver |
3121 // -- esp[0] : return address | 3134 // -- esp[0] : return address |
3122 // ----------------------------------- | 3135 // ----------------------------------- |
3123 Label miss; | 3136 Label miss; |
3124 | 3137 |
3125 __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1); | 3138 Counters* counters = masm()->isolate()->counters(); |
| 3139 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); |
3126 | 3140 |
3127 // Check that the name has not changed. | 3141 // Check that the name has not changed. |
3128 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 3142 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
3129 __ j(not_equal, &miss, not_taken); | 3143 __ j(not_equal, &miss, not_taken); |
3130 | 3144 |
3131 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); | 3145 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); |
3132 __ bind(&miss); | 3146 __ bind(&miss); |
3133 __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1); | 3147 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); |
3134 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3148 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3135 | 3149 |
3136 // Return the generated code. | 3150 // Return the generated code. |
3137 return GetCode(CALLBACKS, name); | 3151 return GetCode(CALLBACKS, name); |
3138 } | 3152 } |
3139 | 3153 |
3140 | 3154 |
3141 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { | 3155 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { |
3142 // ----------- S t a t e ------------- | 3156 // ----------- S t a t e ------------- |
3143 // -- eax : key | 3157 // -- eax : key |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3298 | 3312 |
3299 // Move argc to ebx and retrieve and tag the JSObject to return. | 3313 // Move argc to ebx and retrieve and tag the JSObject to return. |
3300 __ mov(ebx, eax); | 3314 __ mov(ebx, eax); |
3301 __ pop(eax); | 3315 __ pop(eax); |
3302 __ or_(Operand(eax), Immediate(kHeapObjectTag)); | 3316 __ or_(Operand(eax), Immediate(kHeapObjectTag)); |
3303 | 3317 |
3304 // Remove caller arguments and receiver from the stack and return. | 3318 // Remove caller arguments and receiver from the stack and return. |
3305 __ pop(ecx); | 3319 __ pop(ecx); |
3306 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); | 3320 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); |
3307 __ push(ecx); | 3321 __ push(ecx); |
3308 __ IncrementCounter(COUNTERS->constructed_objects(), 1); | 3322 Counters* counters = masm()->isolate()->counters(); |
3309 __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1); | 3323 __ IncrementCounter(counters->constructed_objects(), 1); |
| 3324 __ IncrementCounter(counters->constructed_objects_stub(), 1); |
3310 __ ret(0); | 3325 __ ret(0); |
3311 | 3326 |
3312 // Jump to the generic stub in case the specialized code cannot handle the | 3327 // Jump to the generic stub in case the specialized code cannot handle the |
3313 // construction. | 3328 // construction. |
3314 __ bind(&generic_stub_call); | 3329 __ bind(&generic_stub_call); |
3315 Code* code = Isolate::Current()->builtins()->builtin( | 3330 Code* code = Isolate::Current()->builtins()->builtin( |
3316 Builtins::JSConstructStubGeneric); | 3331 Builtins::JSConstructStubGeneric); |
3317 Handle<Code> generic_construct_stub(code); | 3332 Handle<Code> generic_construct_stub(code); |
3318 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); | 3333 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
3319 | 3334 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3447 | 3462 |
3448 // If we fail allocation of the HeapNumber, we still have a value on | 3463 // If we fail allocation of the HeapNumber, we still have a value on |
3449 // top of the FPU stack. Remove it. | 3464 // top of the FPU stack. Remove it. |
3450 __ bind(&failed_allocation); | 3465 __ bind(&failed_allocation); |
3451 __ ffree(); | 3466 __ ffree(); |
3452 __ fincstp(); | 3467 __ fincstp(); |
3453 // Fall through to slow case. | 3468 // Fall through to slow case. |
3454 | 3469 |
3455 // Slow case: Jump to runtime. | 3470 // Slow case: Jump to runtime. |
3456 __ bind(&slow); | 3471 __ bind(&slow); |
3457 __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1); | 3472 Counters* counters = masm()->isolate()->counters(); |
| 3473 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); |
3458 // ----------- S t a t e ------------- | 3474 // ----------- S t a t e ------------- |
3459 // -- eax : key | 3475 // -- eax : key |
3460 // -- edx : receiver | 3476 // -- edx : receiver |
3461 // -- esp[0] : return address | 3477 // -- esp[0] : return address |
3462 // ----------------------------------- | 3478 // ----------------------------------- |
3463 | 3479 |
3464 __ pop(ebx); | 3480 __ pop(ebx); |
3465 __ push(edx); // receiver | 3481 __ push(edx); // receiver |
3466 __ push(eax); // name | 3482 __ push(eax); // name |
3467 __ push(ebx); // return address | 3483 __ push(ebx); // return address |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3678 | 3694 |
3679 return GetCode(flags); | 3695 return GetCode(flags); |
3680 } | 3696 } |
3681 | 3697 |
3682 | 3698 |
3683 #undef __ | 3699 #undef __ |
3684 | 3700 |
3685 } } // namespace v8::internal | 3701 } } // namespace v8::internal |
3686 | 3702 |
3687 #endif // V8_TARGET_ARCH_IA32 | 3703 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |