Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(247)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 1980483003: [es6] Reintroduce the instanceof operator in the backends. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Igors comments. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/interface-descriptors-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/api-arguments.h" 8 #include "src/api-arguments.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 1984 matching lines...) Expand 10 before | Expand all | Expand 10 after
1995 __ popq(r13); 1995 __ popq(r13);
1996 __ popq(r12); 1996 __ popq(r12);
1997 __ addp(rsp, Immediate(2 * kPointerSize)); // remove markers 1997 __ addp(rsp, Immediate(2 * kPointerSize)); // remove markers
1998 1998
1999 // Restore frame pointer and return. 1999 // Restore frame pointer and return.
2000 __ popq(rbp); 2000 __ popq(rbp);
2001 __ ret(0); 2001 __ ret(0);
2002 } 2002 }
2003 2003
2004 2004
2005 void InstanceOfStub::Generate(MacroAssembler* masm) {
2006 Register const object = rdx; // Object (lhs).
2007 Register const function = rax; // Function (rhs).
2008 Register const object_map = rcx; // Map of {object}.
2009 Register const function_map = r8; // Map of {function}.
2010 Register const function_prototype = rdi; // Prototype of {function}.
2011
2012 DCHECK(object.is(InstanceOfDescriptor::LeftRegister()));
2013 DCHECK(function.is(InstanceOfDescriptor::RightRegister()));
2014
2015 // Check if {object} is a smi.
2016 Label object_is_smi;
2017 __ JumpIfSmi(object, &object_is_smi, Label::kNear);
2018
2019 // Lookup the {function} and the {object} map in the global instanceof cache.
2020 // Note: This is safe because we clear the global instanceof cache whenever
2021 // we change the prototype of any object.
2022 Label fast_case, slow_case;
2023 __ movp(object_map, FieldOperand(object, HeapObject::kMapOffset));
2024 __ CompareRoot(function, Heap::kInstanceofCacheFunctionRootIndex);
2025 __ j(not_equal, &fast_case, Label::kNear);
2026 __ CompareRoot(object_map, Heap::kInstanceofCacheMapRootIndex);
2027 __ j(not_equal, &fast_case, Label::kNear);
2028 __ LoadRoot(rax, Heap::kInstanceofCacheAnswerRootIndex);
2029 __ ret(0);
2030
2031 // If {object} is a smi we can safely return false if {function} is a JS
2032 // function, otherwise we have to miss to the runtime and throw an exception.
2033 __ bind(&object_is_smi);
2034 __ JumpIfSmi(function, &slow_case);
2035 __ CmpObjectType(function, JS_FUNCTION_TYPE, function_map);
2036 __ j(not_equal, &slow_case);
2037 __ LoadRoot(rax, Heap::kFalseValueRootIndex);
2038 __ ret(0);
2039
2040 // Fast-case: The {function} must be a valid JSFunction.
2041 __ bind(&fast_case);
2042 __ JumpIfSmi(function, &slow_case);
2043 __ CmpObjectType(function, JS_FUNCTION_TYPE, function_map);
2044 __ j(not_equal, &slow_case);
2045
2046 // Go to the runtime if the function is not a constructor.
2047 __ testb(FieldOperand(function_map, Map::kBitFieldOffset),
2048 Immediate(1 << Map::kIsConstructor));
2049 __ j(zero, &slow_case);
2050
2051 // Ensure that {function} has an instance prototype.
2052 __ testb(FieldOperand(function_map, Map::kBitFieldOffset),
2053 Immediate(1 << Map::kHasNonInstancePrototype));
2054 __ j(not_zero, &slow_case);
2055
2056 // Get the "prototype" (or initial map) of the {function}.
2057 __ movp(function_prototype,
2058 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
2059 __ AssertNotSmi(function_prototype);
2060
2061 // Resolve the prototype if the {function} has an initial map. Afterwards the
2062 // {function_prototype} will be either the JSReceiver prototype object or the
2063 // hole value, which means that no instances of the {function} were created so
2064 // far and hence we should return false.
2065 Label function_prototype_valid;
2066 Register const function_prototype_map = kScratchRegister;
2067 __ CmpObjectType(function_prototype, MAP_TYPE, function_prototype_map);
2068 __ j(not_equal, &function_prototype_valid, Label::kNear);
2069 __ movp(function_prototype,
2070 FieldOperand(function_prototype, Map::kPrototypeOffset));
2071 __ bind(&function_prototype_valid);
2072 __ AssertNotSmi(function_prototype);
2073
2074 // Update the global instanceof cache with the current {object} map and
2075 // {function}. The cached answer will be set when it is known below.
2076 __ StoreRoot(function, Heap::kInstanceofCacheFunctionRootIndex);
2077 __ StoreRoot(object_map, Heap::kInstanceofCacheMapRootIndex);
2078
2079 // Loop through the prototype chain looking for the {function} prototype.
2080 // Assume true, and change to false if not found.
2081 Label done, loop, fast_runtime_fallback;
2082 __ LoadRoot(rax, Heap::kTrueValueRootIndex);
2083 __ bind(&loop);
2084
2085 __ testb(FieldOperand(object_map, Map::kBitFieldOffset),
2086 Immediate(1 << Map::kIsAccessCheckNeeded));
2087 __ j(not_zero, &fast_runtime_fallback, Label::kNear);
2088 __ CmpInstanceType(object_map, JS_PROXY_TYPE);
2089 __ j(equal, &fast_runtime_fallback, Label::kNear);
2090
2091 __ movp(object, FieldOperand(object_map, Map::kPrototypeOffset));
2092 __ cmpp(object, function_prototype);
2093 __ j(equal, &done, Label::kNear);
2094 __ CompareRoot(object, Heap::kNullValueRootIndex);
2095 __ movp(object_map, FieldOperand(object, HeapObject::kMapOffset));
2096 __ j(not_equal, &loop);
2097 __ LoadRoot(rax, Heap::kFalseValueRootIndex);
2098 __ bind(&done);
2099 __ StoreRoot(rax, Heap::kInstanceofCacheAnswerRootIndex);
2100 __ ret(0);
2101
2102 // Found Proxy or access check needed: Call the runtime.
2103 __ bind(&fast_runtime_fallback);
2104 __ PopReturnAddressTo(kScratchRegister);
2105 __ Push(object);
2106 __ Push(function_prototype);
2107 __ PushReturnAddressFrom(kScratchRegister);
2108 // Invalidate the instanceof cache.
2109 __ Move(rax, Smi::FromInt(0));
2110 __ StoreRoot(rax, Heap::kInstanceofCacheFunctionRootIndex);
2111 __ TailCallRuntime(Runtime::kHasInPrototypeChain);
2112
2113 // Slow-case: Call the %InstanceOf runtime function.
2114 __ bind(&slow_case);
2115 __ PopReturnAddressTo(kScratchRegister);
2116 __ Push(object);
2117 __ Push(function);
2118 __ PushReturnAddressFrom(kScratchRegister);
2119 __ TailCallRuntime(is_es6_instanceof() ? Runtime::kOrdinaryHasInstance
2120 : Runtime::kInstanceOf);
2121 }
2122
2123
2124 // ------------------------------------------------------------------------- 2005 // -------------------------------------------------------------------------
2125 // StringCharCodeAtGenerator 2006 // StringCharCodeAtGenerator
2126 2007
2127 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 2008 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
2128 // If the receiver is a smi trigger the non-string case. 2009 // If the receiver is a smi trigger the non-string case.
2129 if (check_mode_ == RECEIVER_IS_UNKNOWN) { 2010 if (check_mode_ == RECEIVER_IS_UNKNOWN) {
2130 __ JumpIfSmi(object_, receiver_not_string_); 2011 __ JumpIfSmi(object_, receiver_not_string_);
2131 2012
2132 // Fetch the instance type of the receiver into result register. 2013 // Fetch the instance type of the receiver into result register.
2133 __ movp(result_, FieldOperand(object_, HeapObject::kMapOffset)); 2014 __ movp(result_, FieldOperand(object_, HeapObject::kMapOffset));
(...skipping 3436 matching lines...) Expand 10 before | Expand all | Expand 10 after
5570 kStackUnwindSpace, nullptr, return_value_operand, 5451 kStackUnwindSpace, nullptr, return_value_operand,
5571 NULL); 5452 NULL);
5572 } 5453 }
5573 5454
5574 #undef __ 5455 #undef __
5575 5456
5576 } // namespace internal 5457 } // namespace internal
5577 } // namespace v8 5458 } // namespace v8
5578 5459
5579 #endif // V8_TARGET_ARCH_X64 5460 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/interface-descriptors-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698