OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 // must always call a backup property check that is complete. | 82 // must always call a backup property check that is complete. |
83 // This function is safe to call if the receiver has fast properties. | 83 // This function is safe to call if the receiver has fast properties. |
84 // Name must be a symbol and receiver must be a heap object. | 84 // Name must be a symbol and receiver must be a heap object. |
85 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 85 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
86 Label* miss_label, | 86 Label* miss_label, |
87 Register receiver, | 87 Register receiver, |
88 String* name, | 88 String* name, |
89 Register r0, | 89 Register r0, |
90 Register r1) { | 90 Register r1) { |
91 ASSERT(name->IsSymbol()); | 91 ASSERT(name->IsSymbol()); |
92 __ IncrementCounter(COUNTERS->negative_lookups(), 1); | 92 Counters* counters = masm->isolate()->counters(); |
93 __ IncrementCounter(COUNTERS->negative_lookups_miss(), 1); | 93 __ IncrementCounter(counters->negative_lookups(), 1); |
| 94 __ IncrementCounter(counters->negative_lookups_miss(), 1); |
94 | 95 |
95 Label done; | 96 Label done; |
96 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 97 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); |
97 | 98 |
98 const int kInterceptorOrAccessCheckNeededMask = | 99 const int kInterceptorOrAccessCheckNeededMask = |
99 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 100 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
100 | 101 |
101 // Bail out if the receiver has a named interceptor or requires access checks. | 102 // Bail out if the receiver has a named interceptor or requires access checks. |
102 __ testb(FieldOperand(r0, Map::kBitFieldOffset), | 103 __ testb(FieldOperand(r0, Map::kBitFieldOffset), |
103 Immediate(kInterceptorOrAccessCheckNeededMask)); | 104 Immediate(kInterceptorOrAccessCheckNeededMask)); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), | 167 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), |
167 Immediate(kIsSymbolMask)); | 168 Immediate(kIsSymbolMask)); |
168 __ j(zero, miss_label); | 169 __ j(zero, miss_label); |
169 } else { | 170 } else { |
170 // Give up probing if still not found the undefined value. | 171 // Give up probing if still not found the undefined value. |
171 __ j(not_equal, miss_label); | 172 __ j(not_equal, miss_label); |
172 } | 173 } |
173 } | 174 } |
174 | 175 |
175 __ bind(&done); | 176 __ bind(&done); |
176 __ DecrementCounter(COUNTERS->negative_lookups_miss(), 1); | 177 __ DecrementCounter(counters->negative_lookups_miss(), 1); |
177 } | 178 } |
178 | 179 |
179 | 180 |
180 void StubCache::GenerateProbe(MacroAssembler* masm, | 181 void StubCache::GenerateProbe(MacroAssembler* masm, |
181 Code::Flags flags, | 182 Code::Flags flags, |
182 Register receiver, | 183 Register receiver, |
183 Register name, | 184 Register name, |
184 Register scratch, | 185 Register scratch, |
185 Register extra, | 186 Register extra, |
186 Register extra2) { | 187 Register extra2) { |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 interceptor_holder); | 595 interceptor_holder); |
595 if (depth1 == kInvalidProtoDepth) { | 596 if (depth1 == kInvalidProtoDepth) { |
596 depth2 = | 597 depth2 = |
597 optimization.GetPrototypeDepthOfExpectedType(interceptor_holder, | 598 optimization.GetPrototypeDepthOfExpectedType(interceptor_holder, |
598 lookup->holder()); | 599 lookup->holder()); |
599 } | 600 } |
600 can_do_fast_api_call = (depth1 != kInvalidProtoDepth) || | 601 can_do_fast_api_call = (depth1 != kInvalidProtoDepth) || |
601 (depth2 != kInvalidProtoDepth); | 602 (depth2 != kInvalidProtoDepth); |
602 } | 603 } |
603 | 604 |
604 __ IncrementCounter(COUNTERS->call_const_interceptor(), 1); | 605 Counters* counters = masm->isolate()->counters(); |
| 606 __ IncrementCounter(counters->call_const_interceptor(), 1); |
605 | 607 |
606 if (can_do_fast_api_call) { | 608 if (can_do_fast_api_call) { |
607 __ IncrementCounter(COUNTERS->call_const_interceptor_fast_api(), 1); | 609 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1); |
608 ReserveSpaceForFastApiCall(masm, scratch1); | 610 ReserveSpaceForFastApiCall(masm, scratch1); |
609 } | 611 } |
610 | 612 |
611 // Check that the maps from receiver to interceptor's holder | 613 // Check that the maps from receiver to interceptor's holder |
612 // haven't changed and thus we can invoke interceptor. | 614 // haven't changed and thus we can invoke interceptor. |
613 Label miss_cleanup; | 615 Label miss_cleanup; |
614 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 616 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
615 Register holder = | 617 Register holder = |
616 stub_compiler_->CheckPrototypes(object, receiver, | 618 stub_compiler_->CheckPrototypes(object, receiver, |
617 interceptor_holder, scratch1, | 619 interceptor_holder, scratch1, |
(...skipping 1381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1999 | 2001 |
2000 GenerateNameCheck(name, &miss_before_stack_reserved); | 2002 GenerateNameCheck(name, &miss_before_stack_reserved); |
2001 | 2003 |
2002 // Get the receiver from the stack. | 2004 // Get the receiver from the stack. |
2003 const int argc = arguments().immediate(); | 2005 const int argc = arguments().immediate(); |
2004 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2006 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
2005 | 2007 |
2006 // Check that the receiver isn't a smi. | 2008 // Check that the receiver isn't a smi. |
2007 __ JumpIfSmi(rdx, &miss_before_stack_reserved); | 2009 __ JumpIfSmi(rdx, &miss_before_stack_reserved); |
2008 | 2010 |
2009 __ IncrementCounter(COUNTERS->call_const(), 1); | 2011 Counters* counters = masm()->isolate()->counters(); |
2010 __ IncrementCounter(COUNTERS->call_const_fast_api(), 1); | 2012 __ IncrementCounter(counters->call_const(), 1); |
| 2013 __ IncrementCounter(counters->call_const_fast_api(), 1); |
2011 | 2014 |
2012 // Allocate space for v8::Arguments implicit values. Must be initialized | 2015 // Allocate space for v8::Arguments implicit values. Must be initialized |
2013 // before calling any runtime function. | 2016 // before calling any runtime function. |
2014 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); | 2017 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); |
2015 | 2018 |
2016 // Check that the maps haven't changed and find a Holder as a side effect. | 2019 // Check that the maps haven't changed and find a Holder as a side effect. |
2017 CheckPrototypes(JSObject::cast(object), rdx, holder, | 2020 CheckPrototypes(JSObject::cast(object), rdx, holder, |
2018 rbx, rax, rdi, name, depth, &miss); | 2021 rbx, rax, rdi, name, depth, &miss); |
2019 | 2022 |
2020 // Move the return address on top of the stack. | 2023 // Move the return address on top of the stack. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2070 | 2073 |
2071 // Check that the receiver isn't a smi. | 2074 // Check that the receiver isn't a smi. |
2072 if (check != NUMBER_CHECK) { | 2075 if (check != NUMBER_CHECK) { |
2073 __ JumpIfSmi(rdx, &miss); | 2076 __ JumpIfSmi(rdx, &miss); |
2074 } | 2077 } |
2075 | 2078 |
2076 // Make sure that it's okay not to patch the on stack receiver | 2079 // Make sure that it's okay not to patch the on stack receiver |
2077 // unless we're doing a receiver map check. | 2080 // unless we're doing a receiver map check. |
2078 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2081 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
2079 | 2082 |
| 2083 Counters* counters = masm()->isolate()->counters(); |
2080 SharedFunctionInfo* function_info = function->shared(); | 2084 SharedFunctionInfo* function_info = function->shared(); |
2081 switch (check) { | 2085 switch (check) { |
2082 case RECEIVER_MAP_CHECK: | 2086 case RECEIVER_MAP_CHECK: |
2083 __ IncrementCounter(COUNTERS->call_const(), 1); | 2087 __ IncrementCounter(counters->call_const(), 1); |
2084 | 2088 |
2085 // Check that the maps haven't changed. | 2089 // Check that the maps haven't changed. |
2086 CheckPrototypes(JSObject::cast(object), rdx, holder, | 2090 CheckPrototypes(JSObject::cast(object), rdx, holder, |
2087 rbx, rax, rdi, name, &miss); | 2091 rbx, rax, rdi, name, &miss); |
2088 | 2092 |
2089 // Patch the receiver on the stack with the global proxy if | 2093 // Patch the receiver on the stack with the global proxy if |
2090 // necessary. | 2094 // necessary. |
2091 if (object->IsGlobalObject()) { | 2095 if (object->IsGlobalObject()) { |
2092 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 2096 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
2093 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 2097 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2275 // Patch the receiver on the stack with the global proxy. | 2279 // Patch the receiver on the stack with the global proxy. |
2276 if (object->IsGlobalObject()) { | 2280 if (object->IsGlobalObject()) { |
2277 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 2281 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
2278 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 2282 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
2279 } | 2283 } |
2280 | 2284 |
2281 // Setup the context (function already in rdi). | 2285 // Setup the context (function already in rdi). |
2282 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 2286 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
2283 | 2287 |
2284 // Jump to the cached code (tail call). | 2288 // Jump to the cached code (tail call). |
2285 __ IncrementCounter(COUNTERS->call_global_inline(), 1); | 2289 Counters* counters = masm()->isolate()->counters(); |
| 2290 __ IncrementCounter(counters->call_global_inline(), 1); |
2286 ASSERT(function->is_compiled()); | 2291 ASSERT(function->is_compiled()); |
2287 ParameterCount expected(function->shared()->formal_parameter_count()); | 2292 ParameterCount expected(function->shared()->formal_parameter_count()); |
2288 if (V8::UseCrankshaft()) { | 2293 if (V8::UseCrankshaft()) { |
2289 // TODO(kasperl): For now, we always call indirectly through the | 2294 // TODO(kasperl): For now, we always call indirectly through the |
2290 // code field in the function to allow recompilation to take effect | 2295 // code field in the function to allow recompilation to take effect |
2291 // without changing any of the call sites. | 2296 // without changing any of the call sites. |
2292 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 2297 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
2293 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION); | 2298 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION); |
2294 } else { | 2299 } else { |
2295 Handle<Code> code(function->code()); | 2300 Handle<Code> code(function->code()); |
2296 __ InvokeCode(code, expected, arguments(), | 2301 __ InvokeCode(code, expected, arguments(), |
2297 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 2302 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
2298 } | 2303 } |
2299 // Handle call cache miss. | 2304 // Handle call cache miss. |
2300 __ bind(&miss); | 2305 __ bind(&miss); |
2301 __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1); | 2306 __ IncrementCounter(counters->call_global_inline_miss(), 1); |
2302 MaybeObject* maybe_result = GenerateMissBranch(); | 2307 MaybeObject* maybe_result = GenerateMissBranch(); |
2303 if (maybe_result->IsFailure()) return maybe_result; | 2308 if (maybe_result->IsFailure()) return maybe_result; |
2304 | 2309 |
2305 // Return the generated code. | 2310 // Return the generated code. |
2306 return GetCode(NORMAL, name); | 2311 return GetCode(NORMAL, name); |
2307 } | 2312 } |
2308 | 2313 |
2309 | 2314 |
2310 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2315 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, |
2311 int index, | 2316 int index, |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2463 // global object. We bail out to the runtime system to do that. | 2468 // global object. We bail out to the runtime system to do that. |
2464 __ Move(rbx, Handle<JSGlobalPropertyCell>(cell)); | 2469 __ Move(rbx, Handle<JSGlobalPropertyCell>(cell)); |
2465 __ CompareRoot(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), | 2470 __ CompareRoot(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), |
2466 Heap::kTheHoleValueRootIndex); | 2471 Heap::kTheHoleValueRootIndex); |
2467 __ j(equal, &miss); | 2472 __ j(equal, &miss); |
2468 | 2473 |
2469 // Store the value in the cell. | 2474 // Store the value in the cell. |
2470 __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rax); | 2475 __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rax); |
2471 | 2476 |
2472 // Return the value (register rax). | 2477 // Return the value (register rax). |
2473 __ IncrementCounter(COUNTERS->named_store_global_inline(), 1); | 2478 Counters* counters = masm()->isolate()->counters(); |
| 2479 __ IncrementCounter(counters->named_store_global_inline(), 1); |
2474 __ ret(0); | 2480 __ ret(0); |
2475 | 2481 |
2476 // Handle store cache miss. | 2482 // Handle store cache miss. |
2477 __ bind(&miss); | 2483 __ bind(&miss); |
2478 __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1); | 2484 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); |
2479 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2485 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
2480 Builtins::StoreIC_Miss)); | 2486 Builtins::StoreIC_Miss)); |
2481 __ Jump(ic, RelocInfo::CODE_TARGET); | 2487 __ Jump(ic, RelocInfo::CODE_TARGET); |
2482 | 2488 |
2483 // Return the generated code. | 2489 // Return the generated code. |
2484 return GetCode(NORMAL, name); | 2490 return GetCode(NORMAL, name); |
2485 } | 2491 } |
2486 | 2492 |
2487 | 2493 |
2488 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 2494 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, |
2489 int index, | 2495 int index, |
2490 Map* transition, | 2496 Map* transition, |
2491 String* name) { | 2497 String* name) { |
2492 // ----------- S t a t e ------------- | 2498 // ----------- S t a t e ------------- |
2493 // -- rax : value | 2499 // -- rax : value |
2494 // -- rcx : key | 2500 // -- rcx : key |
2495 // -- rdx : receiver | 2501 // -- rdx : receiver |
2496 // -- rsp[0] : return address | 2502 // -- rsp[0] : return address |
2497 // ----------------------------------- | 2503 // ----------------------------------- |
2498 Label miss; | 2504 Label miss; |
2499 | 2505 |
2500 __ IncrementCounter(COUNTERS->keyed_store_field(), 1); | 2506 Counters* counters = masm()->isolate()->counters(); |
| 2507 __ IncrementCounter(counters->keyed_store_field(), 1); |
2501 | 2508 |
2502 // Check that the name has not changed. | 2509 // Check that the name has not changed. |
2503 __ Cmp(rcx, Handle<String>(name)); | 2510 __ Cmp(rcx, Handle<String>(name)); |
2504 __ j(not_equal, &miss); | 2511 __ j(not_equal, &miss); |
2505 | 2512 |
2506 // Generate store field code. Preserves receiver and name on jump to miss. | 2513 // Generate store field code. Preserves receiver and name on jump to miss. |
2507 GenerateStoreField(masm(), | 2514 GenerateStoreField(masm(), |
2508 object, | 2515 object, |
2509 index, | 2516 index, |
2510 transition, | 2517 transition, |
2511 rdx, rcx, rbx, | 2518 rdx, rcx, rbx, |
2512 &miss); | 2519 &miss); |
2513 | 2520 |
2514 // Handle store cache miss. | 2521 // Handle store cache miss. |
2515 __ bind(&miss); | 2522 __ bind(&miss); |
2516 __ DecrementCounter(COUNTERS->keyed_store_field(), 1); | 2523 __ DecrementCounter(counters->keyed_store_field(), 1); |
2517 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2524 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
2518 Builtins::KeyedStoreIC_Miss)); | 2525 Builtins::KeyedStoreIC_Miss)); |
2519 __ Jump(ic, RelocInfo::CODE_TARGET); | 2526 __ Jump(ic, RelocInfo::CODE_TARGET); |
2520 | 2527 |
2521 // Return the generated code. | 2528 // Return the generated code. |
2522 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2529 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
2523 } | 2530 } |
2524 | 2531 |
2525 | 2532 |
2526 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( | 2533 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2754 | 2761 |
2755 // Check for deleted property if property can actually be deleted. | 2762 // Check for deleted property if property can actually be deleted. |
2756 if (!is_dont_delete) { | 2763 if (!is_dont_delete) { |
2757 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 2764 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); |
2758 __ j(equal, &miss); | 2765 __ j(equal, &miss); |
2759 } else if (FLAG_debug_code) { | 2766 } else if (FLAG_debug_code) { |
2760 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 2767 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); |
2761 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 2768 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
2762 } | 2769 } |
2763 | 2770 |
2764 __ IncrementCounter(COUNTERS->named_load_global_stub(), 1); | 2771 Counters* counters = masm()->isolate()->counters(); |
| 2772 __ IncrementCounter(counters->named_load_global_stub(), 1); |
2765 __ movq(rax, rbx); | 2773 __ movq(rax, rbx); |
2766 __ ret(0); | 2774 __ ret(0); |
2767 | 2775 |
2768 __ bind(&miss); | 2776 __ bind(&miss); |
2769 __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1); | 2777 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); |
2770 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2778 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2771 | 2779 |
2772 // Return the generated code. | 2780 // Return the generated code. |
2773 return GetCode(NORMAL, name); | 2781 return GetCode(NORMAL, name); |
2774 } | 2782 } |
2775 | 2783 |
2776 | 2784 |
2777 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, | 2785 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, |
2778 JSObject* receiver, | 2786 JSObject* receiver, |
2779 JSObject* holder, | 2787 JSObject* holder, |
2780 int index) { | 2788 int index) { |
2781 // ----------- S t a t e ------------- | 2789 // ----------- S t a t e ------------- |
2782 // -- rax : key | 2790 // -- rax : key |
2783 // -- rdx : receiver | 2791 // -- rdx : receiver |
2784 // -- rsp[0] : return address | 2792 // -- rsp[0] : return address |
2785 // ----------------------------------- | 2793 // ----------------------------------- |
2786 Label miss; | 2794 Label miss; |
2787 | 2795 |
2788 __ IncrementCounter(COUNTERS->keyed_load_field(), 1); | 2796 Counters* counters = masm()->isolate()->counters(); |
| 2797 __ IncrementCounter(counters->keyed_load_field(), 1); |
2789 | 2798 |
2790 // Check that the name has not changed. | 2799 // Check that the name has not changed. |
2791 __ Cmp(rax, Handle<String>(name)); | 2800 __ Cmp(rax, Handle<String>(name)); |
2792 __ j(not_equal, &miss); | 2801 __ j(not_equal, &miss); |
2793 | 2802 |
2794 GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss); | 2803 GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss); |
2795 | 2804 |
2796 __ bind(&miss); | 2805 __ bind(&miss); |
2797 __ DecrementCounter(COUNTERS->keyed_load_field(), 1); | 2806 __ DecrementCounter(counters->keyed_load_field(), 1); |
2798 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2807 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2799 | 2808 |
2800 // Return the generated code. | 2809 // Return the generated code. |
2801 return GetCode(FIELD, name); | 2810 return GetCode(FIELD, name); |
2802 } | 2811 } |
2803 | 2812 |
2804 | 2813 |
2805 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( | 2814 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( |
2806 String* name, | 2815 String* name, |
2807 JSObject* receiver, | 2816 JSObject* receiver, |
2808 JSObject* holder, | 2817 JSObject* holder, |
2809 AccessorInfo* callback) { | 2818 AccessorInfo* callback) { |
2810 // ----------- S t a t e ------------- | 2819 // ----------- S t a t e ------------- |
2811 // -- rax : key | 2820 // -- rax : key |
2812 // -- rdx : receiver | 2821 // -- rdx : receiver |
2813 // -- rsp[0] : return address | 2822 // -- rsp[0] : return address |
2814 // ----------------------------------- | 2823 // ----------------------------------- |
2815 Label miss; | 2824 Label miss; |
2816 | 2825 |
2817 __ IncrementCounter(COUNTERS->keyed_load_callback(), 1); | 2826 Counters* counters = masm()->isolate()->counters(); |
| 2827 __ IncrementCounter(counters->keyed_load_callback(), 1); |
2818 | 2828 |
2819 // Check that the name has not changed. | 2829 // Check that the name has not changed. |
2820 __ Cmp(rax, Handle<String>(name)); | 2830 __ Cmp(rax, Handle<String>(name)); |
2821 __ j(not_equal, &miss); | 2831 __ j(not_equal, &miss); |
2822 | 2832 |
2823 MaybeObject* result = GenerateLoadCallback(receiver, holder, rdx, rax, rbx, | 2833 MaybeObject* result = GenerateLoadCallback(receiver, holder, rdx, rax, rbx, |
2824 rcx, rdi, callback, name, &miss); | 2834 rcx, rdi, callback, name, &miss); |
2825 if (result->IsFailure()) { | 2835 if (result->IsFailure()) { |
2826 miss.Unuse(); | 2836 miss.Unuse(); |
2827 return result; | 2837 return result; |
2828 } | 2838 } |
2829 | 2839 |
2830 __ bind(&miss); | 2840 __ bind(&miss); |
2831 | 2841 |
2832 __ DecrementCounter(COUNTERS->keyed_load_callback(), 1); | 2842 __ DecrementCounter(counters->keyed_load_callback(), 1); |
2833 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2843 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2834 | 2844 |
2835 // Return the generated code. | 2845 // Return the generated code. |
2836 return GetCode(CALLBACKS, name); | 2846 return GetCode(CALLBACKS, name); |
2837 } | 2847 } |
2838 | 2848 |
2839 | 2849 |
2840 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 2850 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, |
2841 JSObject* receiver, | 2851 JSObject* receiver, |
2842 JSObject* holder, | 2852 JSObject* holder, |
2843 Object* value) { | 2853 Object* value) { |
2844 // ----------- S t a t e ------------- | 2854 // ----------- S t a t e ------------- |
2845 // -- rax : key | 2855 // -- rax : key |
2846 // -- rdx : receiver | 2856 // -- rdx : receiver |
2847 // -- rsp[0] : return address | 2857 // -- rsp[0] : return address |
2848 // ----------------------------------- | 2858 // ----------------------------------- |
2849 Label miss; | 2859 Label miss; |
2850 | 2860 |
2851 __ IncrementCounter(COUNTERS->keyed_load_constant_function(), 1); | 2861 Counters* counters = masm()->isolate()->counters(); |
| 2862 __ IncrementCounter(counters->keyed_load_constant_function(), 1); |
2852 | 2863 |
2853 // Check that the name has not changed. | 2864 // Check that the name has not changed. |
2854 __ Cmp(rax, Handle<String>(name)); | 2865 __ Cmp(rax, Handle<String>(name)); |
2855 __ j(not_equal, &miss); | 2866 __ j(not_equal, &miss); |
2856 | 2867 |
2857 GenerateLoadConstant(receiver, holder, rdx, rbx, rcx, rdi, | 2868 GenerateLoadConstant(receiver, holder, rdx, rbx, rcx, rdi, |
2858 value, name, &miss); | 2869 value, name, &miss); |
2859 __ bind(&miss); | 2870 __ bind(&miss); |
2860 __ DecrementCounter(COUNTERS->keyed_load_constant_function(), 1); | 2871 __ DecrementCounter(counters->keyed_load_constant_function(), 1); |
2861 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2872 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2862 | 2873 |
2863 // Return the generated code. | 2874 // Return the generated code. |
2864 return GetCode(CONSTANT_FUNCTION, name); | 2875 return GetCode(CONSTANT_FUNCTION, name); |
2865 } | 2876 } |
2866 | 2877 |
2867 | 2878 |
2868 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 2879 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
2869 JSObject* holder, | 2880 JSObject* holder, |
2870 String* name) { | 2881 String* name) { |
2871 // ----------- S t a t e ------------- | 2882 // ----------- S t a t e ------------- |
2872 // -- rax : key | 2883 // -- rax : key |
2873 // -- rdx : receiver | 2884 // -- rdx : receiver |
2874 // -- rsp[0] : return address | 2885 // -- rsp[0] : return address |
2875 // ----------------------------------- | 2886 // ----------------------------------- |
2876 Label miss; | 2887 Label miss; |
2877 | 2888 |
2878 __ IncrementCounter(COUNTERS->keyed_load_interceptor(), 1); | 2889 Counters* counters = masm()->isolate()->counters(); |
| 2890 __ IncrementCounter(counters->keyed_load_interceptor(), 1); |
2879 | 2891 |
2880 // Check that the name has not changed. | 2892 // Check that the name has not changed. |
2881 __ Cmp(rax, Handle<String>(name)); | 2893 __ Cmp(rax, Handle<String>(name)); |
2882 __ j(not_equal, &miss); | 2894 __ j(not_equal, &miss); |
2883 | 2895 |
2884 LookupResult lookup; | 2896 LookupResult lookup; |
2885 LookupPostInterceptor(holder, name, &lookup); | 2897 LookupPostInterceptor(holder, name, &lookup); |
2886 GenerateLoadInterceptor(receiver, | 2898 GenerateLoadInterceptor(receiver, |
2887 holder, | 2899 holder, |
2888 &lookup, | 2900 &lookup, |
2889 rdx, | 2901 rdx, |
2890 rax, | 2902 rax, |
2891 rcx, | 2903 rcx, |
2892 rbx, | 2904 rbx, |
2893 rdi, | 2905 rdi, |
2894 name, | 2906 name, |
2895 &miss); | 2907 &miss); |
2896 __ bind(&miss); | 2908 __ bind(&miss); |
2897 __ DecrementCounter(COUNTERS->keyed_load_interceptor(), 1); | 2909 __ DecrementCounter(counters->keyed_load_interceptor(), 1); |
2898 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2910 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2899 | 2911 |
2900 // Return the generated code. | 2912 // Return the generated code. |
2901 return GetCode(INTERCEPTOR, name); | 2913 return GetCode(INTERCEPTOR, name); |
2902 } | 2914 } |
2903 | 2915 |
2904 | 2916 |
2905 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 2917 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { |
2906 // ----------- S t a t e ------------- | 2918 // ----------- S t a t e ------------- |
2907 // -- rax : key | 2919 // -- rax : key |
2908 // -- rdx : receiver | 2920 // -- rdx : receiver |
2909 // -- rsp[0] : return address | 2921 // -- rsp[0] : return address |
2910 // ----------------------------------- | 2922 // ----------------------------------- |
2911 Label miss; | 2923 Label miss; |
2912 | 2924 |
2913 __ IncrementCounter(COUNTERS->keyed_load_array_length(), 1); | 2925 Counters* counters = masm()->isolate()->counters(); |
| 2926 __ IncrementCounter(counters->keyed_load_array_length(), 1); |
2914 | 2927 |
2915 // Check that the name has not changed. | 2928 // Check that the name has not changed. |
2916 __ Cmp(rax, Handle<String>(name)); | 2929 __ Cmp(rax, Handle<String>(name)); |
2917 __ j(not_equal, &miss); | 2930 __ j(not_equal, &miss); |
2918 | 2931 |
2919 GenerateLoadArrayLength(masm(), rdx, rcx, &miss); | 2932 GenerateLoadArrayLength(masm(), rdx, rcx, &miss); |
2920 __ bind(&miss); | 2933 __ bind(&miss); |
2921 __ DecrementCounter(COUNTERS->keyed_load_array_length(), 1); | 2934 __ DecrementCounter(counters->keyed_load_array_length(), 1); |
2922 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2935 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2923 | 2936 |
2924 // Return the generated code. | 2937 // Return the generated code. |
2925 return GetCode(CALLBACKS, name); | 2938 return GetCode(CALLBACKS, name); |
2926 } | 2939 } |
2927 | 2940 |
2928 | 2941 |
2929 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 2942 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { |
2930 // ----------- S t a t e ------------- | 2943 // ----------- S t a t e ------------- |
2931 // -- rax : key | 2944 // -- rax : key |
2932 // -- rdx : receiver | 2945 // -- rdx : receiver |
2933 // -- rsp[0] : return address | 2946 // -- rsp[0] : return address |
2934 // ----------------------------------- | 2947 // ----------------------------------- |
2935 Label miss; | 2948 Label miss; |
2936 | 2949 |
2937 __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1); | 2950 Counters* counters = masm()->isolate()->counters(); |
| 2951 __ IncrementCounter(counters->keyed_load_string_length(), 1); |
2938 | 2952 |
2939 // Check that the name has not changed. | 2953 // Check that the name has not changed. |
2940 __ Cmp(rax, Handle<String>(name)); | 2954 __ Cmp(rax, Handle<String>(name)); |
2941 __ j(not_equal, &miss); | 2955 __ j(not_equal, &miss); |
2942 | 2956 |
2943 GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss, true); | 2957 GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss, true); |
2944 __ bind(&miss); | 2958 __ bind(&miss); |
2945 __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1); | 2959 __ DecrementCounter(counters->keyed_load_string_length(), 1); |
2946 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2960 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2947 | 2961 |
2948 // Return the generated code. | 2962 // Return the generated code. |
2949 return GetCode(CALLBACKS, name); | 2963 return GetCode(CALLBACKS, name); |
2950 } | 2964 } |
2951 | 2965 |
2952 | 2966 |
2953 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 2967 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { |
2954 // ----------- S t a t e ------------- | 2968 // ----------- S t a t e ------------- |
2955 // -- rax : key | 2969 // -- rax : key |
2956 // -- rdx : receiver | 2970 // -- rdx : receiver |
2957 // -- rsp[0] : return address | 2971 // -- rsp[0] : return address |
2958 // ----------------------------------- | 2972 // ----------------------------------- |
2959 Label miss; | 2973 Label miss; |
2960 | 2974 |
2961 __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1); | 2975 Counters* counters = masm()->isolate()->counters(); |
| 2976 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); |
2962 | 2977 |
2963 // Check that the name has not changed. | 2978 // Check that the name has not changed. |
2964 __ Cmp(rax, Handle<String>(name)); | 2979 __ Cmp(rax, Handle<String>(name)); |
2965 __ j(not_equal, &miss); | 2980 __ j(not_equal, &miss); |
2966 | 2981 |
2967 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss); | 2982 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss); |
2968 __ bind(&miss); | 2983 __ bind(&miss); |
2969 __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1); | 2984 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); |
2970 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2985 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2971 | 2986 |
2972 // Return the generated code. | 2987 // Return the generated code. |
2973 return GetCode(CALLBACKS, name); | 2988 return GetCode(CALLBACKS, name); |
2974 } | 2989 } |
2975 | 2990 |
2976 | 2991 |
2977 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { | 2992 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { |
2978 // ----------- S t a t e ------------- | 2993 // ----------- S t a t e ------------- |
2979 // -- rax : key | 2994 // -- rax : key |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3128 __ movq(rbx, rax); | 3143 __ movq(rbx, rax); |
3129 __ movq(rax, rdx); | 3144 __ movq(rax, rdx); |
3130 __ or_(rax, Immediate(kHeapObjectTag)); | 3145 __ or_(rax, Immediate(kHeapObjectTag)); |
3131 | 3146 |
3132 // rax: JSObject | 3147 // rax: JSObject |
3133 // rbx: argc | 3148 // rbx: argc |
3134 // Remove caller arguments and receiver from the stack and return. | 3149 // Remove caller arguments and receiver from the stack and return. |
3135 __ pop(rcx); | 3150 __ pop(rcx); |
3136 __ lea(rsp, Operand(rsp, rbx, times_pointer_size, 1 * kPointerSize)); | 3151 __ lea(rsp, Operand(rsp, rbx, times_pointer_size, 1 * kPointerSize)); |
3137 __ push(rcx); | 3152 __ push(rcx); |
3138 __ IncrementCounter(COUNTERS->constructed_objects(), 1); | 3153 Counters* counters = masm()->isolate()->counters(); |
3139 __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1); | 3154 __ IncrementCounter(counters->constructed_objects(), 1); |
| 3155 __ IncrementCounter(counters->constructed_objects_stub(), 1); |
3140 __ ret(0); | 3156 __ ret(0); |
3141 | 3157 |
3142 // Jump to the generic stub in case the specialized code cannot handle the | 3158 // Jump to the generic stub in case the specialized code cannot handle the |
3143 // construction. | 3159 // construction. |
3144 __ bind(&generic_stub_call); | 3160 __ bind(&generic_stub_call); |
3145 Code* code = Isolate::Current()->builtins()->builtin( | 3161 Code* code = Isolate::Current()->builtins()->builtin( |
3146 Builtins::JSConstructStubGeneric); | 3162 Builtins::JSConstructStubGeneric); |
3147 Handle<Code> generic_construct_stub(code); | 3163 Handle<Code> generic_construct_stub(code); |
3148 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 3164 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
3149 | 3165 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3251 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); | 3267 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); |
3252 __ movq(rax, rcx); | 3268 __ movq(rax, rcx); |
3253 __ ret(0); | 3269 __ ret(0); |
3254 } else { | 3270 } else { |
3255 __ Integer32ToSmi(rax, rcx); | 3271 __ Integer32ToSmi(rax, rcx); |
3256 __ ret(0); | 3272 __ ret(0); |
3257 } | 3273 } |
3258 | 3274 |
3259 // Slow case: Jump to runtime. | 3275 // Slow case: Jump to runtime. |
3260 __ bind(&slow); | 3276 __ bind(&slow); |
3261 __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1); | 3277 Counters* counters = masm()->isolate()->counters(); |
| 3278 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); |
3262 | 3279 |
3263 // ----------- S t a t e ------------- | 3280 // ----------- S t a t e ------------- |
3264 // -- rax : key | 3281 // -- rax : key |
3265 // -- rdx : receiver | 3282 // -- rdx : receiver |
3266 // -- rsp[0] : return address | 3283 // -- rsp[0] : return address |
3267 // ----------------------------------- | 3284 // ----------------------------------- |
3268 | 3285 |
3269 __ pop(rbx); | 3286 __ pop(rbx); |
3270 __ push(rdx); // receiver | 3287 __ push(rdx); // receiver |
3271 __ push(rax); // name | 3288 __ push(rax); // name |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3442 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); | 3459 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); |
3443 | 3460 |
3444 return GetCode(flags); | 3461 return GetCode(flags); |
3445 } | 3462 } |
3446 | 3463 |
3447 #undef __ | 3464 #undef __ |
3448 | 3465 |
3449 } } // namespace v8::internal | 3466 } } // namespace v8::internal |
3450 | 3467 |
3451 #endif // V8_TARGET_ARCH_X64 | 3468 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |