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

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

Issue 279423005: Customized support for feedback on calls to Array. (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
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 2353 matching lines...) Expand 10 before | Expand all | Expand 10 after
2364 __ push(edi); 2364 __ push(edi);
2365 __ push(eax); 2365 __ push(eax);
2366 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 2366 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
2367 __ pop(edi); 2367 __ pop(edi);
2368 } 2368 }
2369 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax); 2369 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax);
2370 __ jmp(cont); 2370 __ jmp(cont);
2371 } 2371 }
2372 2372
2373 2373
2374 void CallFunctionStub::Generate(MacroAssembler* masm) { 2374 static void CallFunctionNoFeedback(MacroAssembler* masm,
2375 int argc, bool needs_checks,
2376 bool call_as_method) {
2375 // edi : the function to call 2377 // edi : the function to call
2376 Label slow, non_function, wrap, cont; 2378 Label slow, non_function, wrap, cont;
2377 2379
2378 if (NeedsChecks()) { 2380 if (needs_checks) {
2379 // Check that the function really is a JavaScript function. 2381 // Check that the function really is a JavaScript function.
2380 __ JumpIfSmi(edi, &non_function); 2382 __ JumpIfSmi(edi, &non_function);
2381 2383
2382 // Goto slow case if we do not have a function. 2384 // Goto slow case if we do not have a function.
2383 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 2385 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2384 __ j(not_equal, &slow); 2386 __ j(not_equal, &slow);
2385 } 2387 }
2386 2388
2387 // Fast-case: Just invoke the function. 2389 // Fast-case: Just invoke the function.
2388 ParameterCount actual(argc_); 2390 ParameterCount actual(argc);
2389 2391
2390 if (CallAsMethod()) { 2392 if (call_as_method) {
2391 if (NeedsChecks()) { 2393 if (needs_checks) {
2392 EmitContinueIfStrictOrNative(masm, &cont); 2394 EmitContinueIfStrictOrNative(masm, &cont);
2393 } 2395 }
2394 2396
2395 // Load the receiver from the stack. 2397 // Load the receiver from the stack.
2396 __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize)); 2398 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize));
2397 2399
2398 if (NeedsChecks()) { 2400 if (call_as_method) {
2399 __ JumpIfSmi(eax, &wrap); 2401 __ JumpIfSmi(eax, &wrap);
2400 2402
2401 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 2403 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
2402 __ j(below, &wrap); 2404 __ j(below, &wrap);
2403 } else { 2405 } else {
2404 __ jmp(&wrap); 2406 __ jmp(&wrap);
2405 } 2407 }
2406 2408
2407 __ bind(&cont); 2409 __ bind(&cont);
2408 } 2410 }
2409 2411
2410 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); 2412 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper());
2411 2413
2412 if (NeedsChecks()) { 2414 if (needs_checks) {
2413 // Slow-case: Non-function called. 2415 // Slow-case: Non-function called.
2414 __ bind(&slow); 2416 __ bind(&slow);
2415 // (non_function is bound in EmitSlowCase) 2417 // (non_function is bound in EmitSlowCase)
2416 EmitSlowCase(isolate(), masm, argc_, &non_function); 2418 EmitSlowCase(masm->isolate(), masm, argc, &non_function);
2417 } 2419 }
2418 2420
2419 if (CallAsMethod()) { 2421 if (call_as_method) {
2420 __ bind(&wrap); 2422 __ bind(&wrap);
2421 EmitWrapCase(masm, argc_, &cont); 2423 EmitWrapCase(masm, argc, &cont);
2422 } 2424 }
2423 } 2425 }
2424 2426
2425 2427
2428 void CallFunctionStub::Generate(MacroAssembler* masm) {
2429 CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod());
2430 }
2431
2432
2426 void CallConstructStub::Generate(MacroAssembler* masm) { 2433 void CallConstructStub::Generate(MacroAssembler* masm) {
2427 // eax : number of arguments 2434 // eax : number of arguments
2428 // ebx : feedback vector 2435 // ebx : feedback vector
2429 // edx : (only if ebx is not the megamorphic symbol) slot in feedback 2436 // edx : (only if ebx is not the megamorphic symbol) slot in feedback
2430 // vector (Smi) 2437 // vector (Smi)
2431 // edi : constructor function 2438 // edi : constructor function
2432 Label slow, non_function_call; 2439 Label slow, non_function_call;
2433 2440
2434 // Check that function is not a smi. 2441 // Check that function is not a smi.
2435 __ JumpIfSmi(edi, &non_function_call); 2442 __ JumpIfSmi(edi, &non_function_call);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 2499
2493 2500
2494 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { 2501 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
2495 __ mov(vector, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 2502 __ mov(vector, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
2496 __ mov(vector, FieldOperand(vector, JSFunction::kSharedFunctionInfoOffset)); 2503 __ mov(vector, FieldOperand(vector, JSFunction::kSharedFunctionInfoOffset));
2497 __ mov(vector, FieldOperand(vector, 2504 __ mov(vector, FieldOperand(vector,
2498 SharedFunctionInfo::kFeedbackVectorOffset)); 2505 SharedFunctionInfo::kFeedbackVectorOffset));
2499 } 2506 }
2500 2507
2501 2508
2509 void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
2510 // edi - function
2511 // ebx - feedback vector
2512 // edx - slot id
2513 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
2514 __ cmp(edi, ecx);
2515 __ j(not_equal, miss);
2516
2517 __ mov(eax, arg_count());
2518 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
2519 FixedArray::kHeaderSize));
2520 // Verify that ecx contains an AllocationSite
2521 __ AssertUndefinedOrAllocationSite(ebx);
2522 ArrayConstructorStub stub(masm->isolate(), arg_count());
2523 __ TailCallStub(&stub);
2524 }
2525
2526
2527 void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
2528 // edi - function
2529 // ebx - feedback vector
2530 // edx - slot id
2531 Label miss;
2532
2533 if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
2534 Generate_MonomorphicArray(masm, &miss);
2535 } else {
2536 // So far there is only one customer for our custom feedback scheme.
2537 UNREACHABLE();
2538 }
2539
2540 __ bind(&miss);
2541 GenerateMiss(masm);
2542
2543 // The slow case, we need this no matter what to complete a call after a miss.
2544 CallFunctionNoFeedback(masm,
2545 arg_count(),
2546 true,
2547 CallAsMethod());
2548
2549 // Unreachable.
2550 __ int3();
danno 2014/05/16 16:34:11 I think there might be a macro for this.
mvstanton 2014/05/19 13:45:24 There isn't, code even in the macro assembler uses
2551 }
2552
2553
2502 void CallICStub::Generate(MacroAssembler* masm) { 2554 void CallICStub::Generate(MacroAssembler* masm) {
2503 // edi - function 2555 // edi - function
2504 // edx - slot id 2556 // edx - slot id
2505 Isolate* isolate = masm->isolate(); 2557 Isolate* isolate = masm->isolate();
2506 Label extra_checks_or_miss, slow_start; 2558 Label extra_checks_or_miss, slow_start;
2507 Label slow, non_function, wrap, cont; 2559 Label slow, non_function, wrap, cont;
2508 Label have_js_function; 2560 Label have_js_function;
2509 int argc = state_.arg_count(); 2561 int argc = state_.arg_count();
2510 ParameterCount actual(argc); 2562 ParameterCount actual(argc);
2511 2563
2512 EmitLoadTypeFeedbackVector(masm, ebx); 2564 EmitLoadTypeFeedbackVector(masm, ebx);
2513 2565
2566 // the MONOMORPHIC_ARRAY case is handled with a helper function.
2567 if (state_.stub_type() != CallIC::DEFAULT) {
2568 Generate_CustomFeedbackCall(masm);
2569 return;
2570 }
2571
2572 // the MONOMORPHIC_ARRAY case is handled with a helper function.
2514 // The checks. First, does edi match the recorded monomorphic target? 2573 // The checks. First, does edi match the recorded monomorphic target?
2515 __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size, 2574 __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size,
2516 FixedArray::kHeaderSize)); 2575 FixedArray::kHeaderSize));
2517 __ j(not_equal, &extra_checks_or_miss); 2576 __ j(not_equal, &extra_checks_or_miss);
2518 2577
2519 __ bind(&have_js_function); 2578 __ bind(&have_js_function);
2520 if (state_.CallAsMethod()) { 2579 if (state_.CallAsMethod()) {
2521 EmitContinueIfStrictOrNative(masm, &cont); 2580 EmitContinueIfStrictOrNative(masm, &cont);
2522 2581
2523 // Load the receiver from the stack. 2582 // Load the receiver from the stack.
(...skipping 2604 matching lines...) Expand 10 before | Expand all | Expand 10 after
5128 Operand(ebp, 7 * kPointerSize), 5187 Operand(ebp, 7 * kPointerSize),
5129 NULL); 5188 NULL);
5130 } 5189 }
5131 5190
5132 5191
5133 #undef __ 5192 #undef __
5134 5193
5135 } } // namespace v8::internal 5194 } } // namespace v8::internal
5136 5195
5137 #endif // V8_TARGET_ARCH_IA32 5196 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698