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