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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 132963012: Pretenure call new support. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comment response. Created 6 years, 10 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 Isolate* isolate, 100 Isolate* isolate,
101 CodeStubInterfaceDescriptor* descriptor) { 101 CodeStubInterfaceDescriptor* descriptor) {
102 static Register registers[] = { eax, ebx, ecx, edx }; 102 static Register registers[] = { eax, ebx, ecx, edx };
103 descriptor->register_param_count_ = 4; 103 descriptor->register_param_count_ = 4;
104 descriptor->register_params_ = registers; 104 descriptor->register_params_ = registers;
105 descriptor->deoptimization_handler_ = 105 descriptor->deoptimization_handler_ =
106 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry; 106 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry;
107 } 107 }
108 108
109 109
110 void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
111 Isolate* isolate,
112 CodeStubInterfaceDescriptor* descriptor) {
113 static Register registers[] = { ebx, edx };
114 descriptor->register_param_count_ = 2;
115 descriptor->register_params_ = registers;
116 descriptor->deoptimization_handler_ = NULL;
117 }
118
119
120 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( 110 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
121 Isolate* isolate, 111 Isolate* isolate,
122 CodeStubInterfaceDescriptor* descriptor) { 112 CodeStubInterfaceDescriptor* descriptor) {
123 static Register registers[] = { edx, ecx }; 113 static Register registers[] = { edx, ecx };
124 descriptor->register_param_count_ = 2; 114 descriptor->register_param_count_ = 2;
125 descriptor->register_params_ = registers; 115 descriptor->register_params_ = registers;
126 descriptor->deoptimization_handler_ = 116 descriptor->deoptimization_handler_ =
127 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); 117 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
128 } 118 }
129 119
(...skipping 2206 matching lines...) Expand 10 before | Expand all | Expand 10 after
2336 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, 2326 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
2337 FixedArray::kHeaderSize)); 2327 FixedArray::kHeaderSize));
2338 2328
2339 // A monomorphic cache hit or an already megamorphic state: invoke the 2329 // A monomorphic cache hit or an already megamorphic state: invoke the
2340 // function without changing the state. 2330 // function without changing the state.
2341 __ cmp(ecx, edi); 2331 __ cmp(ecx, edi);
2342 __ j(equal, &done, Label::kFar); 2332 __ j(equal, &done, Label::kFar);
2343 __ cmp(ecx, Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); 2333 __ cmp(ecx, Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
2344 __ j(equal, &done, Label::kFar); 2334 __ j(equal, &done, Label::kFar);
2345 2335
2346 // If we came here, we need to see if we are the array function.
2347 // If we didn't have a matching function, and we didn't find the megamorph
2348 // sentinel, then we have in the slot either some other function or an
2349 // AllocationSite. Do a map check on the object in ecx.
2350 Handle<Map> allocation_site_map =
2351 masm->isolate()->factory()->allocation_site_map();
2352 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map));
2353 __ j(not_equal, &miss);
2354
2355 // Load the global or builtins object from the current context
2356 __ LoadGlobalContext(ecx);
2357 // Make sure the function is the Array() function
2358 __ cmp(edi, Operand(ecx,
2359 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
2360 __ j(not_equal, &megamorphic);
2361 __ jmp(&done, Label::kFar);
2362
2363 __ bind(&miss); 2336 __ bind(&miss);
2364 2337
2365 // A monomorphic miss (i.e, here the cache is not uninitialized) goes 2338 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
2366 // megamorphic. 2339 // megamorphic.
2367 __ cmp(ecx, Immediate(TypeFeedbackInfo::UninitializedSentinel(isolate))); 2340 __ cmp(ecx, Immediate(TypeFeedbackInfo::UninitializedSentinel(isolate)));
2368 __ j(equal, &initialize); 2341 __ j(equal, &initialize);
2369 // MegamorphicSentinel is an immortal immovable object (undefined) so no 2342 // MegamorphicSentinel is an immortal immovable object (undefined) so no
2370 // write-barrier is needed. 2343 // write-barrier is needed.
2371 __ bind(&megamorphic); 2344 __ bind(&megamorphic);
2372 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, 2345 __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
2373 FixedArray::kHeaderSize), 2346 FixedArray::kHeaderSize),
2374 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); 2347 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
2375 __ jmp(&done, Label::kFar); 2348 __ jmp(&done, Label::kFar);
2376 2349
2377 // An uninitialized cache is patched with the function or sentinel to 2350 // An uninitialized cache is patched with the function or sentinel to
2378 // indicate the ElementsKind if function is the Array constructor. 2351 // indicate the ElementsKind if function is the Array constructor.
2379 __ bind(&initialize); 2352 __ bind(&initialize);
2380 __ LoadGlobalContext(ecx);
2381 // Make sure the function is the Array() function
2382 __ cmp(edi, Operand(ecx,
2383 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
2384 __ j(not_equal, &not_array_function);
2385
2386 // The target function is the Array constructor,
2387 // Create an AllocationSite if we don't already have it, store it in the slot.
2388 {
2389 FrameScope scope(masm, StackFrame::INTERNAL);
2390
2391 // Arguments register must be smi-tagged to call out.
2392 __ SmiTag(eax);
2393 __ push(eax);
2394 __ push(edi);
2395 __ push(edx);
2396 __ push(ebx);
2397
2398 CreateAllocationSiteStub create_stub;
2399 __ CallStub(&create_stub);
2400
2401 __ pop(ebx);
2402 __ pop(edx);
2403 __ pop(edi);
2404 __ pop(eax);
2405 __ SmiUntag(eax);
2406 }
2407 __ jmp(&done);
2408
2409 __ bind(&not_array_function);
2410 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, 2353 __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
2411 FixedArray::kHeaderSize), 2354 FixedArray::kHeaderSize),
2412 edi); 2355 edi);
2413 // We won't need edx or ebx anymore, just save edi 2356 // We won't need edx or ebx anymore, just save edi
2414 __ push(edi); 2357 __ push(edi);
2415 __ push(ebx); 2358 __ push(ebx);
2416 __ push(edx); 2359 __ push(edx);
2417 __ RecordWriteArray(ebx, edi, edx, kDontSaveFPRegs, 2360 __ RecordWriteArray(ebx, edi, edx, kDontSaveFPRegs,
2418 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 2361 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
2419 __ pop(edx); 2362 __ pop(edx);
(...skipping 14 matching lines...) Expand all
2434 if (NeedsChecks()) { 2377 if (NeedsChecks()) {
2435 // Check that the function really is a JavaScript function. 2378 // Check that the function really is a JavaScript function.
2436 __ JumpIfSmi(edi, &non_function); 2379 __ JumpIfSmi(edi, &non_function);
2437 2380
2438 // Goto slow case if we do not have a function. 2381 // Goto slow case if we do not have a function.
2439 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 2382 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2440 __ j(not_equal, &slow); 2383 __ j(not_equal, &slow);
2441 2384
2442 if (RecordCallTarget()) { 2385 if (RecordCallTarget()) {
2443 GenerateRecordCallTarget(masm); 2386 GenerateRecordCallTarget(masm);
2387 // Type information was updated. Because we may call Array, which
2388 // expects either undefined or an AllocationSite in ebx we need
2389 // to set ebx to undefined.
2390 __ mov(ebx, Immediate(isolate->factory()->undefined_value()));
2444 } 2391 }
2445 } 2392 }
2446 2393
2447 // Fast-case: Just invoke the function. 2394 // Fast-case: Just invoke the function.
2448 ParameterCount actual(argc_); 2395 ParameterCount actual(argc_);
2449 2396
2450 if (CallAsMethod()) { 2397 if (CallAsMethod()) {
2451 if (NeedsChecks()) { 2398 if (NeedsChecks()) {
2452 // Do not transform the receiver for strict mode functions. 2399 // Do not transform the receiver for strict mode functions.
2453 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 2400 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2537 Label slow, non_function_call; 2484 Label slow, non_function_call;
2538 2485
2539 // Check that function is not a smi. 2486 // Check that function is not a smi.
2540 __ JumpIfSmi(edi, &non_function_call); 2487 __ JumpIfSmi(edi, &non_function_call);
2541 // Check that function is a JSFunction. 2488 // Check that function is a JSFunction.
2542 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 2489 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2543 __ j(not_equal, &slow); 2490 __ j(not_equal, &slow);
2544 2491
2545 if (RecordCallTarget()) { 2492 if (RecordCallTarget()) {
2546 GenerateRecordCallTarget(masm); 2493 GenerateRecordCallTarget(masm);
2494 // Put the AllocationSite from the feedback vector into ebx.
2495 // By adding kPointerSize we encode that we know the AllocationSite
2496 // entry is at the feedback vector slot given by edx + 1.
2497 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
2498 FixedArray::kHeaderSize + kPointerSize));
2499 __ AssertUndefinedOrAllocationSite(ebx);
2547 } 2500 }
2548 2501
2549 // Jump to the function-specific construct stub. 2502 // Jump to the function-specific construct stub.
2550 Register jmp_reg = ecx; 2503 Register jmp_reg = ecx;
2551 __ mov(jmp_reg, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 2504 __ mov(jmp_reg, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2552 __ mov(jmp_reg, FieldOperand(jmp_reg, 2505 __ mov(jmp_reg, FieldOperand(jmp_reg,
2553 SharedFunctionInfo::kConstructStubOffset)); 2506 SharedFunctionInfo::kConstructStubOffset));
2554 __ lea(jmp_reg, FieldOperand(jmp_reg, Code::kHeaderSize)); 2507 __ lea(jmp_reg, FieldOperand(jmp_reg, Code::kHeaderSize));
2555 __ jmp(jmp_reg); 2508 __ jmp(jmp_reg);
2556 2509
(...skipping 22 matching lines...) Expand all
2579 return false; 2532 return false;
2580 } 2533 }
2581 2534
2582 2535
2583 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { 2536 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
2584 CEntryStub::GenerateAheadOfTime(isolate); 2537 CEntryStub::GenerateAheadOfTime(isolate);
2585 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); 2538 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
2586 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); 2539 StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
2587 // It is important that the store buffer overflow stubs are generated first. 2540 // It is important that the store buffer overflow stubs are generated first.
2588 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); 2541 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
2589 CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
2590 if (Serializer::enabled()) { 2542 if (Serializer::enabled()) {
2591 PlatformFeatureScope sse2(SSE2); 2543 PlatformFeatureScope sse2(SSE2);
2592 BinaryOpICStub::GenerateAheadOfTime(isolate); 2544 BinaryOpICStub::GenerateAheadOfTime(isolate);
2593 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate); 2545 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
2594 } else { 2546 } else {
2595 BinaryOpICStub::GenerateAheadOfTime(isolate); 2547 BinaryOpICStub::GenerateAheadOfTime(isolate);
2596 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate); 2548 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
2597 } 2549 }
2598 } 2550 }
2599 2551
(...skipping 2548 matching lines...) Expand 10 before | Expand all | Expand 10 after
5148 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); 5100 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
5149 } else { 5101 } else {
5150 UNREACHABLE(); 5102 UNREACHABLE();
5151 } 5103 }
5152 } 5104 }
5153 5105
5154 5106
5155 void ArrayConstructorStub::Generate(MacroAssembler* masm) { 5107 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
5156 // ----------- S t a t e ------------- 5108 // ----------- S t a t e -------------
5157 // -- eax : argc (only if argument_count_ == ANY) 5109 // -- eax : argc (only if argument_count_ == ANY)
5158 // -- ebx : feedback vector (fixed array or undefined) 5110 // -- ebx : AllocationSite or undefined
5159 // -- edx : slot index (if ebx is fixed array)
5160 // -- edi : constructor 5111 // -- edi : constructor
5161 // -- esp[0] : return address 5112 // -- esp[0] : return address
5162 // -- esp[4] : last argument 5113 // -- esp[4] : last argument
5163 // ----------------------------------- 5114 // -----------------------------------
5164 Handle<Object> undefined_sentinel( 5115 Handle<Object> undefined_sentinel(
5165 masm->isolate()->heap()->undefined_value(), 5116 masm->isolate()->heap()->undefined_value(),
5166 masm->isolate()); 5117 masm->isolate());
5167 5118
5168 if (FLAG_debug_code) { 5119 if (FLAG_debug_code) {
5169 // The array construct code is only set for the global and natives 5120 // The array construct code is only set for the global and natives
5170 // builtin Array functions which always have maps. 5121 // builtin Array functions which always have maps.
5171 5122
5172 // Initial map for the builtin Array function should be a map. 5123 // Initial map for the builtin Array function should be a map.
5173 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); 5124 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
5174 // Will both indicate a NULL and a Smi. 5125 // Will both indicate a NULL and a Smi.
5175 __ test(ecx, Immediate(kSmiTagMask)); 5126 __ test(ecx, Immediate(kSmiTagMask));
5176 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); 5127 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction);
5177 __ CmpObjectType(ecx, MAP_TYPE, ecx); 5128 __ CmpObjectType(ecx, MAP_TYPE, ecx);
5178 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); 5129 __ Assert(equal, kUnexpectedInitialMapForArrayFunction);
5179 5130
5180 // We should either have undefined in ebx or a valid fixed array. 5131 // We should either have undefined in ebx or a valid AllocationSite
5181 Label okay_here; 5132 __ AssertUndefinedOrAllocationSite(ebx);
5182 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map();
5183 __ cmp(ebx, Immediate(undefined_sentinel));
5184 __ j(equal, &okay_here);
5185 __ cmp(FieldOperand(ebx, 0), Immediate(fixed_array_map));
5186 __ Assert(equal, kExpectedFixedArrayInRegisterEbx);
5187
5188 // edx should be a smi if we don't have undefined in ebx.
5189 __ AssertSmi(edx);
5190
5191 __ bind(&okay_here);
5192 } 5133 }
5193 5134
5194 Label no_info; 5135 Label no_info;
5195 // If the feedback vector is undefined, or contains anything other than an 5136 // If the feedback vector is undefined, or contains anything other than an
5196 // AllocationSite, call an array constructor that doesn't use AllocationSites. 5137 // AllocationSite, call an array constructor that doesn't use AllocationSites.
5197 __ cmp(ebx, Immediate(undefined_sentinel)); 5138 __ cmp(ebx, Immediate(undefined_sentinel));
5198 __ j(equal, &no_info); 5139 __ j(equal, &no_info);
5199 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
5200 FixedArray::kHeaderSize));
5201 __ cmp(FieldOperand(ebx, 0), Immediate(
5202 masm->isolate()->factory()->allocation_site_map()));
5203 __ j(not_equal, &no_info);
5204 5140
5205 // Only look at the lower 16 bits of the transition info. 5141 // Only look at the lower 16 bits of the transition info.
5206 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset)); 5142 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset));
5207 __ SmiUntag(edx); 5143 __ SmiUntag(edx);
5208 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); 5144 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0);
5209 __ and_(edx, Immediate(AllocationSite::ElementsKindBits::kMask)); 5145 __ and_(edx, Immediate(AllocationSite::ElementsKindBits::kMask));
5210 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); 5146 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
5211 5147
5212 __ bind(&no_info); 5148 __ bind(&no_info);
5213 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); 5149 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
5453 Operand(ebp, 7 * kPointerSize), 5389 Operand(ebp, 7 * kPointerSize),
5454 NULL); 5390 NULL);
5455 } 5391 }
5456 5392
5457 5393
5458 #undef __ 5394 #undef __
5459 5395
5460 } } // namespace v8::internal 5396 } } // namespace v8::internal
5461 5397
5462 #endif // V8_TARGET_ARCH_IA32 5398 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698