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

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

Issue 292433016: Revert "Reland r21346 "Inobject slack tracking is done on a per-closure basis instead of per-shared… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 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 | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.cc ('k') | src/mark-compact.h » ('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 #include "v8.h" 5 #include "v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "codegen.h" 9 #include "codegen.h"
10 #include "deoptimizer.h" 10 #include "deoptimizer.h"
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 CallRuntimePassFunction(masm, Runtime::kHiddenTryInstallOptimizedCode); 95 CallRuntimePassFunction(masm, Runtime::kHiddenTryInstallOptimizedCode);
96 GenerateTailCallToReturnedCode(masm); 96 GenerateTailCallToReturnedCode(masm);
97 97
98 __ bind(&ok); 98 __ bind(&ok);
99 GenerateTailCallToSharedCode(masm); 99 GenerateTailCallToSharedCode(masm);
100 } 100 }
101 101
102 102
103 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 103 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
104 bool is_api_function, 104 bool is_api_function,
105 bool count_constructions,
105 bool create_memento) { 106 bool create_memento) {
106 // ----------- S t a t e ------------- 107 // ----------- S t a t e -------------
107 // -- eax: number of arguments 108 // -- eax: number of arguments
108 // -- edi: constructor function 109 // -- edi: constructor function
109 // -- ebx: allocation site or undefined 110 // -- ebx: allocation site or undefined
110 // ----------------------------------- 111 // -----------------------------------
111 112
113 // Should never count constructions for api objects.
114 ASSERT(!is_api_function || !count_constructions);
115
112 // Should never create mementos for api functions. 116 // Should never create mementos for api functions.
113 ASSERT(!is_api_function || !create_memento); 117 ASSERT(!is_api_function || !create_memento);
114 118
119 // Should never create mementos before slack tracking is finished.
120 ASSERT(!count_constructions || !create_memento);
121
115 // Enter a construct frame. 122 // Enter a construct frame.
116 { 123 {
117 FrameScope scope(masm, StackFrame::CONSTRUCT); 124 FrameScope scope(masm, StackFrame::CONSTRUCT);
118 125
119 if (create_memento) { 126 if (create_memento) {
120 __ AssertUndefinedOrAllocationSite(ebx); 127 __ AssertUndefinedOrAllocationSite(ebx);
121 __ push(ebx); 128 __ push(ebx);
122 } 129 }
123 130
124 // Store a smi-tagged arguments count on the stack. 131 // Store a smi-tagged arguments count on the stack.
(...skipping 25 matching lines...) Expand all
150 __ j(not_equal, &rt_call); 157 __ j(not_equal, &rt_call);
151 158
152 // Check that the constructor is not constructing a JSFunction (see 159 // Check that the constructor is not constructing a JSFunction (see
153 // comments in Runtime_NewObject in runtime.cc). In which case the 160 // comments in Runtime_NewObject in runtime.cc). In which case the
154 // initial map's instance type would be JS_FUNCTION_TYPE. 161 // initial map's instance type would be JS_FUNCTION_TYPE.
155 // edi: constructor 162 // edi: constructor
156 // eax: initial map 163 // eax: initial map
157 __ CmpInstanceType(eax, JS_FUNCTION_TYPE); 164 __ CmpInstanceType(eax, JS_FUNCTION_TYPE);
158 __ j(equal, &rt_call); 165 __ j(equal, &rt_call);
159 166
160 if (!is_api_function) { 167 if (count_constructions) {
161 Label allocate; 168 Label allocate;
162 // The code below relies on these assumptions.
163 STATIC_ASSERT(JSFunction::kNoSlackTracking == 0);
164 STATIC_ASSERT(Map::ConstructionCount::kShift +
165 Map::ConstructionCount::kSize == 32);
166 // Check if slack tracking is enabled.
167 __ mov(esi, FieldOperand(eax, Map::kBitField3Offset));
168 __ shr(esi, Map::ConstructionCount::kShift);
169 __ j(zero, &allocate); // JSFunction::kNoSlackTracking
170 // Decrease generous allocation count. 169 // Decrease generous allocation count.
171 __ sub(FieldOperand(eax, Map::kBitField3Offset), 170 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
172 Immediate(1 << Map::ConstructionCount::kShift)); 171 __ dec_b(FieldOperand(ecx,
173 172 SharedFunctionInfo::kConstructionCountOffset));
174 __ cmp(esi, JSFunction::kFinishSlackTracking); 173 __ j(not_zero, &allocate);
175 __ j(not_equal, &allocate);
176 174
177 __ push(eax); 175 __ push(eax);
178 __ push(edi); 176 __ push(edi);
179 177
180 __ push(edi); // constructor 178 __ push(edi); // constructor
179 // The call will replace the stub, so the countdown is only done once.
181 __ CallRuntime(Runtime::kHiddenFinalizeInstanceSize, 1); 180 __ CallRuntime(Runtime::kHiddenFinalizeInstanceSize, 1);
182 181
183 __ pop(edi); 182 __ pop(edi);
184 __ pop(eax); 183 __ pop(eax);
185 __ xor_(esi, esi); // JSFunction::kNoSlackTracking
186 184
187 __ bind(&allocate); 185 __ bind(&allocate);
188 } 186 }
189 187
190 // Now allocate the JSObject on the heap. 188 // Now allocate the JSObject on the heap.
191 // edi: constructor 189 // edi: constructor
192 // eax: initial map 190 // eax: initial map
193 __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset)); 191 __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset));
194 __ shl(edi, kPointerSizeLog2); 192 __ shl(edi, kPointerSizeLog2);
195 if (create_memento) { 193 if (create_memento) {
196 __ add(edi, Immediate(AllocationMemento::kSize)); 194 __ add(edi, Immediate(AllocationMemento::kSize));
197 } 195 }
198 196
199 __ Allocate(edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS); 197 __ Allocate(edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS);
200 198
201 Factory* factory = masm->isolate()->factory(); 199 Factory* factory = masm->isolate()->factory();
202 200
203 // Allocated the JSObject, now initialize the fields. 201 // Allocated the JSObject, now initialize the fields.
204 // eax: initial map 202 // eax: initial map
205 // ebx: JSObject 203 // ebx: JSObject
206 // edi: start of next object (including memento if create_memento) 204 // edi: start of next object (including memento if create_memento)
207 __ mov(Operand(ebx, JSObject::kMapOffset), eax); 205 __ mov(Operand(ebx, JSObject::kMapOffset), eax);
208 __ mov(ecx, factory->empty_fixed_array()); 206 __ mov(ecx, factory->empty_fixed_array());
209 __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx); 207 __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx);
210 __ mov(Operand(ebx, JSObject::kElementsOffset), ecx); 208 __ mov(Operand(ebx, JSObject::kElementsOffset), ecx);
211 // Set extra fields in the newly allocated object. 209 // Set extra fields in the newly allocated object.
212 // eax: initial map 210 // eax: initial map
213 // ebx: JSObject 211 // ebx: JSObject
214 // edi: start of next object (including memento if create_memento) 212 // edi: start of next object (including memento if create_memento)
215 // esi: slack tracking counter (non-API function case) 213 __ lea(ecx, Operand(ebx, JSObject::kHeaderSize));
216 __ mov(edx, factory->undefined_value()); 214 __ mov(edx, factory->undefined_value());
217 __ lea(ecx, Operand(ebx, JSObject::kHeaderSize)); 215 if (count_constructions) {
218 if (!is_api_function) {
219 Label no_inobject_slack_tracking;
220
221 // Check if slack tracking is enabled.
222 __ cmp(esi, JSFunction::kNoSlackTracking);
223 __ j(equal, &no_inobject_slack_tracking);
224
225 // Allocate object with a slack.
226 __ movzx_b(esi, 216 __ movzx_b(esi,
227 FieldOperand(eax, Map::kPreAllocatedPropertyFieldsOffset)); 217 FieldOperand(eax, Map::kPreAllocatedPropertyFieldsOffset));
228 __ lea(esi, 218 __ lea(esi,
229 Operand(ebx, esi, times_pointer_size, JSObject::kHeaderSize)); 219 Operand(ebx, esi, times_pointer_size, JSObject::kHeaderSize));
230 // esi: offset of first field after pre-allocated fields 220 // esi: offset of first field after pre-allocated fields
231 if (FLAG_debug_code) { 221 if (FLAG_debug_code) {
232 __ cmp(esi, edi); 222 __ cmp(esi, edi);
233 __ Assert(less_equal, 223 __ Assert(less_equal,
234 kUnexpectedNumberOfPreAllocatedPropertyFields); 224 kUnexpectedNumberOfPreAllocatedPropertyFields);
235 } 225 }
236 __ InitializeFieldsWithFiller(ecx, esi, edx); 226 __ InitializeFieldsWithFiller(ecx, esi, edx);
237 __ mov(edx, factory->one_pointer_filler_map()); 227 __ mov(edx, factory->one_pointer_filler_map());
238 // Fill the remaining fields with one pointer filler map. 228 __ InitializeFieldsWithFiller(ecx, edi, edx);
239 229 } else if (create_memento) {
240 __ bind(&no_inobject_slack_tracking);
241 }
242
243 if (create_memento) {
244 __ lea(esi, Operand(edi, -AllocationMemento::kSize)); 230 __ lea(esi, Operand(edi, -AllocationMemento::kSize));
245 __ InitializeFieldsWithFiller(ecx, esi, edx); 231 __ InitializeFieldsWithFiller(ecx, esi, edx);
246 232
247 // Fill in memento fields if necessary. 233 // Fill in memento fields if necessary.
248 // esi: points to the allocated but uninitialized memento. 234 // esi: points to the allocated but uninitialized memento.
235 Handle<Map> allocation_memento_map = factory->allocation_memento_map();
249 __ mov(Operand(esi, AllocationMemento::kMapOffset), 236 __ mov(Operand(esi, AllocationMemento::kMapOffset),
250 factory->allocation_memento_map()); 237 allocation_memento_map);
251 // Get the cell or undefined. 238 // Get the cell or undefined.
252 __ mov(edx, Operand(esp, kPointerSize*2)); 239 __ mov(edx, Operand(esp, kPointerSize*2));
253 __ mov(Operand(esi, AllocationMemento::kAllocationSiteOffset), 240 __ mov(Operand(esi, AllocationMemento::kAllocationSiteOffset),
254 edx); 241 edx);
255 } else { 242 } else {
256 __ InitializeFieldsWithFiller(ecx, edi, edx); 243 __ InitializeFieldsWithFiller(ecx, edi, edx);
257 } 244 }
258 245
259 // Add the object tag to make the JSObject real, so that we can continue 246 // Add the object tag to make the JSObject real, so that we can continue
260 // and jump into the continuation code at any time from now on. Any 247 // and jump into the continuation code at any time from now on. Any
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 // Allocate the new receiver object using the runtime call. 333 // Allocate the new receiver object using the runtime call.
347 __ bind(&rt_call); 334 __ bind(&rt_call);
348 int offset = 0; 335 int offset = 0;
349 if (create_memento) { 336 if (create_memento) {
350 // Get the cell or allocation site. 337 // Get the cell or allocation site.
351 __ mov(edi, Operand(esp, kPointerSize * 2)); 338 __ mov(edi, Operand(esp, kPointerSize * 2));
352 __ push(edi); 339 __ push(edi);
353 offset = kPointerSize; 340 offset = kPointerSize;
354 } 341 }
355 342
356 // Must restore esi (context) and edi (constructor) before calling runtime. 343 // Must restore edi (constructor) before calling runtime.
357 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
358 __ mov(edi, Operand(esp, offset)); 344 __ mov(edi, Operand(esp, offset));
359 // edi: function (constructor) 345 // edi: function (constructor)
360 __ push(edi); 346 __ push(edi);
361 if (create_memento) { 347 if (create_memento) {
362 __ CallRuntime(Runtime::kHiddenNewObjectWithAllocationSite, 2); 348 __ CallRuntime(Runtime::kHiddenNewObjectWithAllocationSite, 2);
363 } else { 349 } else {
364 __ CallRuntime(Runtime::kHiddenNewObject, 1); 350 __ CallRuntime(Runtime::kHiddenNewObject, 1);
365 } 351 }
366 __ mov(ebx, eax); // store result in ebx 352 __ mov(ebx, eax); // store result in ebx
367 353
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 Handle<Code> code = 406 Handle<Code> code =
421 masm->isolate()->builtins()->HandleApiCallConstruct(); 407 masm->isolate()->builtins()->HandleApiCallConstruct();
422 __ call(code, RelocInfo::CODE_TARGET); 408 __ call(code, RelocInfo::CODE_TARGET);
423 } else { 409 } else {
424 ParameterCount actual(eax); 410 ParameterCount actual(eax);
425 __ InvokeFunction(edi, actual, CALL_FUNCTION, 411 __ InvokeFunction(edi, actual, CALL_FUNCTION,
426 NullCallWrapper()); 412 NullCallWrapper());
427 } 413 }
428 414
429 // Store offset of return address for deoptimizer. 415 // Store offset of return address for deoptimizer.
430 if (!is_api_function) { 416 if (!is_api_function && !count_constructions) {
431 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 417 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
432 } 418 }
433 419
434 // Restore context from the frame. 420 // Restore context from the frame.
435 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 421 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
436 422
437 // If the result is an object (in the ECMA sense), we should get rid 423 // If the result is an object (in the ECMA sense), we should get rid
438 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 424 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
439 // on page 74. 425 // on page 74.
440 Label use_receiver, exit; 426 Label use_receiver, exit;
(...skipping 21 matching lines...) Expand all
462 // Remove caller arguments from the stack and return. 448 // Remove caller arguments from the stack and return.
463 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 449 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
464 __ pop(ecx); 450 __ pop(ecx);
465 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver 451 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
466 __ push(ecx); 452 __ push(ecx);
467 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1); 453 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1);
468 __ ret(0); 454 __ ret(0);
469 } 455 }
470 456
471 457
458 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
459 Generate_JSConstructStubHelper(masm, false, true, false);
460 }
461
462
472 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 463 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
473 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new); 464 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
474 } 465 }
475 466
476 467
477 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 468 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
478 Generate_JSConstructStubHelper(masm, true, false); 469 Generate_JSConstructStubHelper(masm, true, false, false);
479 } 470 }
480 471
481 472
482 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, 473 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
483 bool is_construct) { 474 bool is_construct) {
484 ProfileEntryHookStub::MaybeCallEntryHook(masm); 475 ProfileEntryHookStub::MaybeCallEntryHook(masm);
485 476
486 // Clear the context before we push it when entering the internal frame. 477 // Clear the context before we push it when entering the internal frame.
487 __ Move(esi, Immediate(0)); 478 __ Move(esi, Immediate(0));
488 479
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 1434
1444 __ bind(&ok); 1435 __ bind(&ok);
1445 __ ret(0); 1436 __ ret(0);
1446 } 1437 }
1447 1438
1448 #undef __ 1439 #undef __
1449 } 1440 }
1450 } // namespace v8::internal 1441 } // namespace v8::internal
1451 1442
1452 #endif // V8_TARGET_ARCH_IA32 1443 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/mark-compact.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698