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

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

Issue 295933012: Revert "Inobject slack tracking is done on a per-closure basis instead of per-shared info basis." (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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 Handle<Code> code = 406 Handle<Code> code =
420 masm->isolate()->builtins()->HandleApiCallConstruct(); 407 masm->isolate()->builtins()->HandleApiCallConstruct();
421 __ call(code, RelocInfo::CODE_TARGET); 408 __ call(code, RelocInfo::CODE_TARGET);
422 } else { 409 } else {
423 ParameterCount actual(eax); 410 ParameterCount actual(eax);
424 __ InvokeFunction(edi, actual, CALL_FUNCTION, 411 __ InvokeFunction(edi, actual, CALL_FUNCTION,
425 NullCallWrapper()); 412 NullCallWrapper());
426 } 413 }
427 414
428 // Store offset of return address for deoptimizer. 415 // Store offset of return address for deoptimizer.
429 if (!is_api_function) { 416 if (!is_api_function && !count_constructions) {
430 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 417 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
431 } 418 }
432 419
433 // Restore context from the frame. 420 // Restore context from the frame.
434 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 421 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
435 422
436 // 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
437 // 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
438 // on page 74. 425 // on page 74.
439 Label use_receiver, exit; 426 Label use_receiver, exit;
(...skipping 21 matching lines...) Expand all
461 // Remove caller arguments from the stack and return. 448 // Remove caller arguments from the stack and return.
462 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 449 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
463 __ pop(ecx); 450 __ pop(ecx);
464 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver 451 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
465 __ push(ecx); 452 __ push(ecx);
466 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1); 453 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1);
467 __ ret(0); 454 __ ret(0);
468 } 455 }
469 456
470 457
458 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
459 Generate_JSConstructStubHelper(masm, false, true, false);
460 }
461
462
471 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 463 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
472 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new); 464 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
473 } 465 }
474 466
475 467
476 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 468 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
477 Generate_JSConstructStubHelper(masm, true, false); 469 Generate_JSConstructStubHelper(masm, true, false, false);
478 } 470 }
479 471
480 472
481 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, 473 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
482 bool is_construct) { 474 bool is_construct) {
483 ProfileEntryHookStub::MaybeCallEntryHook(masm); 475 ProfileEntryHookStub::MaybeCallEntryHook(masm);
484 476
485 // 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.
486 __ Move(esi, Immediate(0)); 478 __ Move(esi, Immediate(0));
487 479
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 1434
1443 __ bind(&ok); 1435 __ bind(&ok);
1444 __ ret(0); 1436 __ ret(0);
1445 } 1437 }
1446 1438
1447 #undef __ 1439 #undef __
1448 } 1440 }
1449 } // namespace v8::internal 1441 } // namespace v8::internal
1450 1442
1451 #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