| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1996 ASSERT(kExceptionObjectReg == RAX); | 1996 ASSERT(kExceptionObjectReg == RAX); |
| 1997 ASSERT(kStackTraceObjectReg == RDX); | 1997 ASSERT(kStackTraceObjectReg == RDX); |
| 1998 __ movq(RBP, RDX); // target frame pointer. | 1998 __ movq(RBP, RDX); // target frame pointer. |
| 1999 __ movq(kStackTraceObjectReg, R8); // stacktrace object. | 1999 __ movq(kStackTraceObjectReg, R8); // stacktrace object. |
| 2000 __ movq(kExceptionObjectReg, RCX); // exception object. | 2000 __ movq(kExceptionObjectReg, RCX); // exception object. |
| 2001 __ movq(RSP, RSI); // target stack_pointer. | 2001 __ movq(RSP, RSI); // target stack_pointer. |
| 2002 __ jmp(RDI); // Jump to the exception handler code. | 2002 __ jmp(RDI); // Jump to the exception handler code. |
| 2003 } | 2003 } |
| 2004 | 2004 |
| 2005 | 2005 |
| 2006 // Implements equality operator when one of the arguments is null | |
| 2007 // (identity check) and updates ICData if necessary. | |
| 2008 // TOS + 0: return address | |
| 2009 // TOS + 1: right argument | |
| 2010 // TOS + 2: left argument | |
| 2011 // RBX: ICData. | |
| 2012 // RAX: result. | |
| 2013 // TODO(srdjan): Move to VM stubs once Boolean objects become VM objects. | |
| 2014 void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) { | |
| 2015 static const intptr_t kNumArgsTested = 2; | |
| 2016 #if defined(DEBUG) | |
| 2017 { Label ok; | |
| 2018 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); | |
| 2019 __ cmpq(RCX, Immediate(kNumArgsTested)); | |
| 2020 __ j(EQUAL, &ok, Assembler::kNearJump); | |
| 2021 __ Stop("Incorrect ICData for equality"); | |
| 2022 __ Bind(&ok); | |
| 2023 } | |
| 2024 #endif // DEBUG | |
| 2025 // Check IC data, update if needed. | |
| 2026 // RBX: IC data object (preserved). | |
| 2027 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset())); | |
| 2028 // R12: ic_data_array with check entries: classes and target functions. | |
| 2029 __ leaq(R12, FieldAddress(R12, Array::data_offset())); | |
| 2030 // R12: points directly to the first ic data array element. | |
| 2031 | |
| 2032 Label get_class_id_as_smi, no_match, loop, compute_result, found; | |
| 2033 __ Bind(&loop); | |
| 2034 // Check left. | |
| 2035 __ movq(RAX, Address(RSP, 2 * kWordSize)); | |
| 2036 __ call(&get_class_id_as_smi); | |
| 2037 __ movq(R13, Address(R12, 0 * kWordSize)); | |
| 2038 __ cmpq(RAX, R13); // Class id match? | |
| 2039 __ j(NOT_EQUAL, &no_match, Assembler::kNearJump); | |
| 2040 // Check right. | |
| 2041 __ movq(RAX, Address(RSP, 1 * kWordSize)); | |
| 2042 __ call(&get_class_id_as_smi); | |
| 2043 __ movq(R13, Address(R12, 1 * kWordSize)); | |
| 2044 __ cmpq(RAX, R13); // Class id match? | |
| 2045 __ j(EQUAL, &found, Assembler::kNearJump); | |
| 2046 __ Bind(&no_match); | |
| 2047 // Next check group. | |
| 2048 __ addq(R12, Immediate( | |
| 2049 kWordSize * ICData::TestEntryLengthFor(kNumArgsTested))); | |
| 2050 __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done? | |
| 2051 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | |
| 2052 Label update_ic_data; | |
| 2053 __ jmp(&update_ic_data); | |
| 2054 | |
| 2055 __ Bind(&found); | |
| 2056 const intptr_t count_offset = | |
| 2057 ICData::CountIndexFor(kNumArgsTested) * kWordSize; | |
| 2058 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); | |
| 2059 __ j(NO_OVERFLOW, &compute_result); | |
| 2060 __ movq(Address(R12, count_offset), | |
| 2061 Immediate(Smi::RawValue(Smi::kMaxValue))); | |
| 2062 | |
| 2063 __ Bind(&compute_result); | |
| 2064 Label true_label; | |
| 2065 __ movq(RAX, Address(RSP, 1 * kWordSize)); | |
| 2066 __ cmpq(RAX, Address(RSP, 2 * kWordSize)); | |
| 2067 __ j(EQUAL, &true_label, Assembler::kNearJump); | |
| 2068 __ LoadObject(RAX, Bool::False(), PP); | |
| 2069 __ ret(); | |
| 2070 __ Bind(&true_label); | |
| 2071 __ LoadObject(RAX, Bool::True(), PP); | |
| 2072 __ ret(); | |
| 2073 | |
| 2074 __ Bind(&get_class_id_as_smi); | |
| 2075 Label not_smi; | |
| 2076 // Test if Smi -> load Smi class for comparison. | |
| 2077 __ testq(RAX, Immediate(kSmiTagMask)); | |
| 2078 __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); | |
| 2079 __ movq(RAX, Immediate(Smi::RawValue(kSmiCid))); | |
| 2080 __ ret(); | |
| 2081 | |
| 2082 __ Bind(¬_smi); | |
| 2083 __ LoadClassId(RAX, RAX); | |
| 2084 __ SmiTag(RAX); | |
| 2085 __ ret(); | |
| 2086 | |
| 2087 __ Bind(&update_ic_data); | |
| 2088 | |
| 2089 // RBX: ICData | |
| 2090 __ movq(RAX, Address(RSP, 1 * kWordSize)); | |
| 2091 __ movq(R13, Address(RSP, 2 * kWordSize)); | |
| 2092 __ EnterStubFrameWithPP(); | |
| 2093 __ pushq(R13); // arg 0 | |
| 2094 __ pushq(RAX); // arg 1 | |
| 2095 __ PushObject(Symbols::EqualOperator(), PP); // Target's name. | |
| 2096 __ pushq(RBX); // ICData | |
| 2097 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4); | |
| 2098 __ Drop(4); | |
| 2099 __ LeaveFrameWithPP(); | |
| 2100 | |
| 2101 __ jmp(&compute_result, Assembler::kNearJump); | |
| 2102 } | |
| 2103 | |
| 2104 // Calls to the runtime to optimize the given function. | 2006 // Calls to the runtime to optimize the given function. |
| 2105 // RDI: function to be reoptimized. | 2007 // RDI: function to be reoptimized. |
| 2106 // R10: argument descriptor (preserved). | 2008 // R10: argument descriptor (preserved). |
| 2107 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 2009 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
| 2108 __ EnterStubFrameWithPP(); | 2010 __ EnterStubFrameWithPP(); |
| 2109 __ LoadObject(R12, Object::null_object(), PP); | 2011 __ LoadObject(R12, Object::null_object(), PP); |
| 2110 __ pushq(R10); | 2012 __ pushq(R10); |
| 2111 __ pushq(R12); // Setup space on stack for return value. | 2013 __ pushq(R12); // Setup space on stack for return value. |
| 2112 __ pushq(RDI); | 2014 __ pushq(RDI); |
| 2113 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 2015 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 __ movq(right, Address(RSP, 3 * kWordSize)); | 2134 __ movq(right, Address(RSP, 3 * kWordSize)); |
| 2233 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 2135 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
| 2234 __ popq(right); | 2136 __ popq(right); |
| 2235 __ popq(left); | 2137 __ popq(left); |
| 2236 __ ret(); | 2138 __ ret(); |
| 2237 } | 2139 } |
| 2238 | 2140 |
| 2239 } // namespace dart | 2141 } // namespace dart |
| 2240 | 2142 |
| 2241 #endif // defined TARGET_ARCH_X64 | 2143 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |