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 |