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

Side by Side Diff: src/x64/builtins-x64.cc

Issue 1488023002: Fix inobject slack tracking for both subclassing and non-subclassing cases. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Moved and updated comments about slack tracking Created 5 years 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/runtime/runtime-object.cc ('k') | test/cctest/cctest.gyp » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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-factory.h" 7 #include "src/code-factory.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 // rdi: constructor 164 // rdi: constructor
165 // rax: initial map (if proven valid below) 165 // rax: initial map (if proven valid below)
166 __ CmpObjectType(rax, MAP_TYPE, rbx); 166 __ CmpObjectType(rax, MAP_TYPE, rbx);
167 __ j(not_equal, &rt_call); 167 __ j(not_equal, &rt_call);
168 168
169 // Fall back to runtime if the expected base constructor and base 169 // Fall back to runtime if the expected base constructor and base
170 // constructor differ. 170 // constructor differ.
171 __ cmpp(rdi, FieldOperand(rax, Map::kConstructorOrBackPointerOffset)); 171 __ cmpp(rdi, FieldOperand(rax, Map::kConstructorOrBackPointerOffset));
172 __ j(not_equal, &rt_call); 172 __ j(not_equal, &rt_call);
173 173
174 if (!is_api_function) {
175 Label allocate;
176 // The code below relies on these assumptions.
177 STATIC_ASSERT(Map::Counter::kShift + Map::Counter::kSize == 32);
178 // Check if slack tracking is enabled.
179 __ movl(rsi, FieldOperand(rax, Map::kBitField3Offset));
180 __ shrl(rsi, Immediate(Map::Counter::kShift));
181 __ cmpl(rsi, Immediate(Map::kSlackTrackingCounterEnd));
182 __ j(less, &allocate);
183 // Decrease generous allocation count.
184 __ subl(FieldOperand(rax, Map::kBitField3Offset),
185 Immediate(1 << Map::Counter::kShift));
186
187 __ cmpl(rsi, Immediate(Map::kSlackTrackingCounterEnd));
188 __ j(not_equal, &allocate);
189
190 // Push the constructor, new_target and map to the stack, and
191 // the map again as an argument to the runtime call.
192 __ Push(rax);
193 __ Push(rdx);
194 __ Push(rdi);
195
196 __ Push(rax); // initial map
197 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
198
199 __ Pop(rdi);
200 __ Pop(rdx);
201 __ Pop(rax);
202 __ movl(rsi, Immediate(Map::kSlackTrackingCounterEnd - 1));
203
204 __ bind(&allocate);
205 }
206
207 // Now allocate the JSObject on the heap. 174 // Now allocate the JSObject on the heap.
208 __ movzxbp(r9, FieldOperand(rax, Map::kInstanceSizeOffset)); 175 __ movzxbp(r9, FieldOperand(rax, Map::kInstanceSizeOffset));
209 __ shlp(r9, Immediate(kPointerSizeLog2)); 176 __ shlp(r9, Immediate(kPointerSizeLog2));
210 // r9: size of new object 177 // r9: size of new object
211 __ Allocate(r9, rbx, r9, no_reg, &rt_call, NO_ALLOCATION_FLAGS); 178 __ Allocate(r9, rbx, r9, no_reg, &rt_call, NO_ALLOCATION_FLAGS);
212 // Allocated the JSObject, now initialize the fields. 179 // Allocated the JSObject, now initialize the fields.
213 // rdi: constructor 180 // rdi: constructor
214 // rdx: new target 181 // rdx: new target
215 // rax: initial map 182 // rax: initial map
216 // rbx: JSObject (not HeapObject tagged - the actual address). 183 // rbx: JSObject (not HeapObject tagged - the actual address).
217 // r9: start of next object 184 // r9: start of next object
218 __ movp(Operand(rbx, JSObject::kMapOffset), rax); 185 __ movp(Operand(rbx, JSObject::kMapOffset), rax);
219 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); 186 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
220 __ movp(Operand(rbx, JSObject::kPropertiesOffset), rcx); 187 __ movp(Operand(rbx, JSObject::kPropertiesOffset), rcx);
221 __ movp(Operand(rbx, JSObject::kElementsOffset), rcx); 188 __ movp(Operand(rbx, JSObject::kElementsOffset), rcx);
222 // Set extra fields in the newly allocated object.
223 // rax: initial map
224 // rdx: new target
225 // rbx: JSObject
226 // r9: start of next object
227 // rsi: slack tracking counter (non-API function case)
228 __ leap(rcx, Operand(rbx, JSObject::kHeaderSize)); 189 __ leap(rcx, Operand(rbx, JSObject::kHeaderSize));
190
191 // Add the object tag to make the JSObject real, so that we can continue
192 // and jump into the continuation code at any time from now on.
193 __ orp(rbx, Immediate(kHeapObjectTag));
194
195 // Fill all the in-object properties with the appropriate filler.
196 // rbx: JSObject (tagged)
197 // rcx: First in-object property of JSObject (not tagged)
229 __ LoadRoot(r11, Heap::kUndefinedValueRootIndex); 198 __ LoadRoot(r11, Heap::kUndefinedValueRootIndex);
199
230 if (!is_api_function) { 200 if (!is_api_function) {
231 Label no_inobject_slack_tracking; 201 Label no_inobject_slack_tracking;
232 202
203 // The code below relies on these assumptions.
204 STATIC_ASSERT(Map::Counter::kShift + Map::Counter::kSize == 32);
233 // Check if slack tracking is enabled. 205 // Check if slack tracking is enabled.
206 __ movl(rsi, FieldOperand(rax, Map::kBitField3Offset));
207 __ shrl(rsi, Immediate(Map::Counter::kShift));
234 __ cmpl(rsi, Immediate(Map::kSlackTrackingCounterEnd)); 208 __ cmpl(rsi, Immediate(Map::kSlackTrackingCounterEnd));
235 __ j(less, &no_inobject_slack_tracking); 209 __ j(less, &no_inobject_slack_tracking);
210 __ Push(rsi); // Save allocation count value.
211 // Decrease generous allocation count.
212 __ subl(FieldOperand(rax, Map::kBitField3Offset),
213 Immediate(1 << Map::Counter::kShift));
236 214
237 // Allocate object with a slack. 215 // Allocate object with a slack.
238 __ movzxbp(rsi, FieldOperand(rax, Map::kUnusedPropertyFieldsOffset)); 216 __ movzxbp(rsi, FieldOperand(rax, Map::kUnusedPropertyFieldsOffset));
239 __ negp(rsi); 217 __ negp(rsi);
240 __ leap(rsi, Operand(r9, rsi, times_pointer_size, 0)); 218 __ leap(rsi, Operand(r9, rsi, times_pointer_size, 0));
241 // rsi: offset of first field after pre-allocated fields 219 // rsi: offset of first field after pre-allocated fields
242 if (FLAG_debug_code) { 220 if (FLAG_debug_code) {
243 __ cmpp(rcx, rsi); 221 __ cmpp(rcx, rsi);
244 __ Assert(less_equal, 222 __ Assert(less_equal,
245 kUnexpectedNumberOfPreAllocatedPropertyFields); 223 kUnexpectedNumberOfPreAllocatedPropertyFields);
246 } 224 }
247 __ InitializeFieldsWithFiller(rcx, rsi, r11); 225 __ InitializeFieldsWithFiller(rcx, rsi, r11);
248 226
249 // To allow truncation fill the remaining fields with one pointer 227 // To allow truncation fill the remaining fields with one pointer
250 // filler map. 228 // filler map.
251 __ LoadRoot(r11, Heap::kOnePointerFillerMapRootIndex); 229 __ LoadRoot(r11, Heap::kOnePointerFillerMapRootIndex);
230 __ InitializeFieldsWithFiller(rcx, r9, r11);
231
232 __ Pop(rsi); // Restore allocation count value before decreasing.
233 __ cmpl(rsi, Immediate(Map::kSlackTrackingCounterEnd));
234 __ j(not_equal, &allocated);
235
236 // Push the constructor, new_target and the object to the stack,
237 // and then the initial map as an argument to the runtime call.
238 __ Push(rdi);
239 __ Push(rdx);
240 __ Push(rbx);
241
242 __ Push(rax); // initial map
243 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
244
245 __ Pop(rbx);
246 __ Pop(rdx);
247 __ Pop(rdi);
248
249 // Continue with JSObject being successfully allocated.
250 // rdi: constructor
251 // rdx: new target
252 // rbx: JSObject (tagged)
253 __ jmp(&allocated);
252 254
253 __ bind(&no_inobject_slack_tracking); 255 __ bind(&no_inobject_slack_tracking);
254 } 256 }
255 257
256 __ InitializeFieldsWithFiller(rcx, r9, r11); 258 __ InitializeFieldsWithFiller(rcx, r9, r11);
257 259
258 // Add the object tag to make the JSObject real, so that we can continue
259 // and jump into the continuation code at any time from now on.
260 // rbx: JSObject (untagged)
261 __ orp(rbx, Immediate(kHeapObjectTag));
262
263 // Continue with JSObject being successfully allocated 260 // Continue with JSObject being successfully allocated
264 // rdi: constructor 261 // rdi: constructor
265 // rdx: new target 262 // rdx: new target
266 // rbx: JSObject (tagged) 263 // rbx: JSObject (tagged)
267 __ jmp(&allocated); 264 __ jmp(&allocated);
268 } 265 }
269 266
270 // Allocate the new receiver object using the runtime call. 267 // Allocate the new receiver object using the runtime call.
271 // rdi: constructor 268 // rdi: constructor
272 // rdx: new target 269 // rdx: new target
(...skipping 1788 matching lines...) Expand 10 before | Expand all | Expand 10 after
2061 __ ret(0); 2058 __ ret(0);
2062 } 2059 }
2063 2060
2064 2061
2065 #undef __ 2062 #undef __
2066 2063
2067 } // namespace internal 2064 } // namespace internal
2068 } // namespace v8 2065 } // namespace v8
2069 2066
2070 #endif // V8_TARGET_ARCH_X64 2067 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/runtime/runtime-object.cc ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698