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

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

Issue 305493003: Reland "Customized support for feedback on calls to Array." and follow-up fixes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Bugfix and tests 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/ic.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 "bootstrapper.h" 9 #include "bootstrapper.h"
10 #include "code-stubs.h" 10 #include "code-stubs.h"
(...skipping 2317 matching lines...) Expand 10 before | Expand all | Expand 10 after
2328 __ push(edi); 2328 __ push(edi);
2329 __ push(eax); 2329 __ push(eax);
2330 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 2330 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
2331 __ pop(edi); 2331 __ pop(edi);
2332 } 2332 }
2333 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax); 2333 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax);
2334 __ jmp(cont); 2334 __ jmp(cont);
2335 } 2335 }
2336 2336
2337 2337
2338 void CallFunctionStub::Generate(MacroAssembler* masm) { 2338 static void CallFunctionNoFeedback(MacroAssembler* masm,
2339 int argc, bool needs_checks,
2340 bool call_as_method) {
2339 // edi : the function to call 2341 // edi : the function to call
2340 Label slow, non_function, wrap, cont; 2342 Label slow, non_function, wrap, cont;
2341 2343
2342 if (NeedsChecks()) { 2344 if (needs_checks) {
2343 // Check that the function really is a JavaScript function. 2345 // Check that the function really is a JavaScript function.
2344 __ JumpIfSmi(edi, &non_function); 2346 __ JumpIfSmi(edi, &non_function);
2345 2347
2346 // Goto slow case if we do not have a function. 2348 // Goto slow case if we do not have a function.
2347 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 2349 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2348 __ j(not_equal, &slow); 2350 __ j(not_equal, &slow);
2349 } 2351 }
2350 2352
2351 // Fast-case: Just invoke the function. 2353 // Fast-case: Just invoke the function.
2352 ParameterCount actual(argc_); 2354 ParameterCount actual(argc);
2353 2355
2354 if (CallAsMethod()) { 2356 if (call_as_method) {
2355 if (NeedsChecks()) { 2357 if (needs_checks) {
2356 EmitContinueIfStrictOrNative(masm, &cont); 2358 EmitContinueIfStrictOrNative(masm, &cont);
2357 } 2359 }
2358 2360
2359 // Load the receiver from the stack. 2361 // Load the receiver from the stack.
2360 __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize)); 2362 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize));
2361 2363
2362 if (NeedsChecks()) { 2364 if (call_as_method) {
2363 __ JumpIfSmi(eax, &wrap); 2365 __ JumpIfSmi(eax, &wrap);
2364 2366
2365 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 2367 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
2366 __ j(below, &wrap); 2368 __ j(below, &wrap);
2367 } else { 2369 } else {
2368 __ jmp(&wrap); 2370 __ jmp(&wrap);
2369 } 2371 }
2370 2372
2371 __ bind(&cont); 2373 __ bind(&cont);
2372 } 2374 }
2373 2375
2374 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); 2376 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper());
2375 2377
2376 if (NeedsChecks()) { 2378 if (needs_checks) {
2377 // Slow-case: Non-function called. 2379 // Slow-case: Non-function called.
2378 __ bind(&slow); 2380 __ bind(&slow);
2379 // (non_function is bound in EmitSlowCase) 2381 // (non_function is bound in EmitSlowCase)
2380 EmitSlowCase(isolate(), masm, argc_, &non_function); 2382 EmitSlowCase(masm->isolate(), masm, argc, &non_function);
2381 } 2383 }
2382 2384
2383 if (CallAsMethod()) { 2385 if (call_as_method) {
2384 __ bind(&wrap); 2386 __ bind(&wrap);
2385 EmitWrapCase(masm, argc_, &cont); 2387 EmitWrapCase(masm, argc, &cont);
2386 } 2388 }
2387 } 2389 }
2388 2390
2389 2391
2392 void CallFunctionStub::Generate(MacroAssembler* masm) {
2393 CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod());
2394 }
2395
2396
2390 void CallConstructStub::Generate(MacroAssembler* masm) { 2397 void CallConstructStub::Generate(MacroAssembler* masm) {
2391 // eax : number of arguments 2398 // eax : number of arguments
2392 // ebx : feedback vector 2399 // ebx : feedback vector
2393 // edx : (only if ebx is not the megamorphic symbol) slot in feedback 2400 // edx : (only if ebx is not the megamorphic symbol) slot in feedback
2394 // vector (Smi) 2401 // vector (Smi)
2395 // edi : constructor function 2402 // edi : constructor function
2396 Label slow, non_function_call; 2403 Label slow, non_function_call;
2397 2404
2398 // Check that function is not a smi. 2405 // Check that function is not a smi.
2399 __ JumpIfSmi(edi, &non_function_call); 2406 __ JumpIfSmi(edi, &non_function_call);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2456 2463
2457 2464
2458 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { 2465 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
2459 __ mov(vector, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 2466 __ mov(vector, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
2460 __ mov(vector, FieldOperand(vector, JSFunction::kSharedFunctionInfoOffset)); 2467 __ mov(vector, FieldOperand(vector, JSFunction::kSharedFunctionInfoOffset));
2461 __ mov(vector, FieldOperand(vector, 2468 __ mov(vector, FieldOperand(vector,
2462 SharedFunctionInfo::kFeedbackVectorOffset)); 2469 SharedFunctionInfo::kFeedbackVectorOffset));
2463 } 2470 }
2464 2471
2465 2472
2473 void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
2474 // edi - function
2475 // ebx - feedback vector
2476 // edx - slot id
2477 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
2478 __ cmp(edi, ecx);
2479 __ j(not_equal, miss);
2480
2481 __ mov(eax, arg_count());
2482 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
2483 FixedArray::kHeaderSize));
2484 // Verify that ecx contains an AllocationSite
2485 __ AssertUndefinedOrAllocationSite(ebx);
2486 ArrayConstructorStub stub(masm->isolate(), arg_count());
2487 __ TailCallStub(&stub);
2488 }
2489
2490
2491 void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
2492 // edi - function
2493 // ebx - feedback vector
2494 // edx - slot id
2495 Label miss;
2496
2497 if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
2498 Generate_MonomorphicArray(masm, &miss);
2499 } else {
2500 // So far there is only one customer for our custom feedback scheme.
2501 UNREACHABLE();
2502 }
2503
2504 __ bind(&miss);
2505 GenerateMiss(masm);
2506
2507 // The slow case, we need this no matter what to complete a call after a miss.
2508 CallFunctionNoFeedback(masm,
2509 arg_count(),
2510 true,
2511 CallAsMethod());
2512
2513 // Unreachable.
2514 __ int3();
2515 }
2516
2517
2466 void CallICStub::Generate(MacroAssembler* masm) { 2518 void CallICStub::Generate(MacroAssembler* masm) {
2467 // edi - function 2519 // edi - function
2468 // edx - slot id 2520 // edx - slot id
2469 Isolate* isolate = masm->isolate(); 2521 Isolate* isolate = masm->isolate();
2470 Label extra_checks_or_miss, slow_start; 2522 Label extra_checks_or_miss, slow_start;
2471 Label slow, non_function, wrap, cont; 2523 Label slow, non_function, wrap, cont;
2472 Label have_js_function; 2524 Label have_js_function;
2473 int argc = state_.arg_count(); 2525 int argc = state_.arg_count();
2474 ParameterCount actual(argc); 2526 ParameterCount actual(argc);
2475 2527
2476 EmitLoadTypeFeedbackVector(masm, ebx); 2528 EmitLoadTypeFeedbackVector(masm, ebx);
2477 2529
2530 if (state_.stub_type() != CallIC::DEFAULT) {
2531 Generate_CustomFeedbackCall(masm);
2532 return;
2533 }
2534
2478 // The checks. First, does edi match the recorded monomorphic target? 2535 // The checks. First, does edi match the recorded monomorphic target?
2479 __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size, 2536 __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size,
2480 FixedArray::kHeaderSize)); 2537 FixedArray::kHeaderSize));
2481 __ j(not_equal, &extra_checks_or_miss); 2538 __ j(not_equal, &extra_checks_or_miss);
2482 2539
2483 __ bind(&have_js_function); 2540 __ bind(&have_js_function);
2484 if (state_.CallAsMethod()) { 2541 if (state_.CallAsMethod()) {
2485 EmitContinueIfStrictOrNative(masm, &cont); 2542 EmitContinueIfStrictOrNative(masm, &cont);
2486 2543
2487 // Load the receiver from the stack. 2544 // Load the receiver from the stack.
(...skipping 2587 matching lines...) Expand 10 before | Expand all | Expand 10 after
5075 Operand(ebp, 7 * kPointerSize), 5132 Operand(ebp, 7 * kPointerSize),
5076 NULL); 5133 NULL);
5077 } 5134 }
5078 5135
5079 5136
5080 #undef __ 5137 #undef __
5081 5138
5082 } } // namespace v8::internal 5139 } } // namespace v8::internal
5083 5140
5084 #endif // V8_TARGET_ARCH_IA32 5141 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698