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

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

Issue 148223002: Remove CallICs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Update test262 status file 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
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/full-codegen-ia32.cc » ('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 // 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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 void KeyedLoadFieldStub::InitializeInterfaceDescriptor( 163 void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
164 Isolate* isolate, 164 Isolate* isolate,
165 CodeStubInterfaceDescriptor* descriptor) { 165 CodeStubInterfaceDescriptor* descriptor) {
166 static Register registers[] = { edx }; 166 static Register registers[] = { edx };
167 descriptor->register_param_count_ = 1; 167 descriptor->register_param_count_ = 1;
168 descriptor->register_params_ = registers; 168 descriptor->register_params_ = registers;
169 descriptor->deoptimization_handler_ = NULL; 169 descriptor->deoptimization_handler_ = NULL;
170 } 170 }
171 171
172 172
173 void KeyedArrayCallStub::InitializeInterfaceDescriptor(
174 Isolate* isolate,
175 CodeStubInterfaceDescriptor* descriptor) {
176 static Register registers[] = { ecx };
177 descriptor->register_param_count_ = 1;
178 descriptor->register_params_ = registers;
179 descriptor->continuation_type_ = TAIL_CALL_CONTINUATION;
180 descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
181 descriptor->deoptimization_handler_ =
182 FUNCTION_ADDR(KeyedCallIC_MissFromStubFailure);
183 }
184
185
186 void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( 173 void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
187 Isolate* isolate, 174 Isolate* isolate,
188 CodeStubInterfaceDescriptor* descriptor) { 175 CodeStubInterfaceDescriptor* descriptor) {
189 static Register registers[] = { edx, ecx, eax }; 176 static Register registers[] = { edx, ecx, eax };
190 descriptor->register_param_count_ = 3; 177 descriptor->register_param_count_ = 3;
191 descriptor->register_params_ = registers; 178 descriptor->register_params_ = registers;
192 descriptor->deoptimization_handler_ = 179 descriptor->deoptimization_handler_ =
193 FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure); 180 FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure);
194 } 181 }
195 182
(...skipping 2223 matching lines...) Expand 10 before | Expand all | Expand 10 after
2419 // No need for a write barrier here - cells are rescanned. 2406 // No need for a write barrier here - cells are rescanned.
2420 2407
2421 __ bind(&done); 2408 __ bind(&done);
2422 } 2409 }
2423 2410
2424 2411
2425 void CallFunctionStub::Generate(MacroAssembler* masm) { 2412 void CallFunctionStub::Generate(MacroAssembler* masm) {
2426 // ebx : cache cell for call target 2413 // ebx : cache cell for call target
2427 // edi : the function to call 2414 // edi : the function to call
2428 Isolate* isolate = masm->isolate(); 2415 Isolate* isolate = masm->isolate();
2429 Label slow, non_function; 2416 Label slow, non_function, wrap, cont;
2430 2417
2431 // Check that the function really is a JavaScript function. 2418 if (NeedsChecks()) {
2432 __ JumpIfSmi(edi, &non_function); 2419 // Check that the function really is a JavaScript function.
2420 __ JumpIfSmi(edi, &non_function);
2433 2421
2434 // Goto slow case if we do not have a function. 2422 // Goto slow case if we do not have a function.
2435 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 2423 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2436 __ j(not_equal, &slow); 2424 __ j(not_equal, &slow);
2437 2425
2438 if (RecordCallTarget()) { 2426 if (RecordCallTarget()) {
2439 GenerateRecordCallTarget(masm); 2427 GenerateRecordCallTarget(masm);
2428 }
2440 } 2429 }
2441 2430
2442 // Fast-case: Just invoke the function. 2431 // Fast-case: Just invoke the function.
2443 ParameterCount actual(argc_); 2432 ParameterCount actual(argc_);
2444 2433
2434 if (CallAsMethod()) {
2435 if (NeedsChecks()) {
2436 // Do not transform the receiver for strict mode functions.
2437 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2438 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset),
2439 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
2440 __ j(not_equal, &cont);
2441
2442 // Do not transform the receiver for natives (shared already in ecx).
2443 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset),
2444 1 << SharedFunctionInfo::kNativeBitWithinByte);
2445 __ j(not_equal, &cont);
2446 }
2447
2448 // Load the receiver from the stack.
2449 __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize));
2450
2451 if (NeedsChecks()) {
2452 __ JumpIfSmi(eax, &wrap);
2453
2454 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
2455 __ j(below, &wrap);
2456 } else {
2457 __ jmp(&wrap);
2458 }
2459
2460 __ bind(&cont);
2461 }
2462
2445 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); 2463 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper());
2446 2464
2447 // Slow-case: Non-function called. 2465 if (NeedsChecks()) {
2448 __ bind(&slow); 2466 // Slow-case: Non-function called.
2449 if (RecordCallTarget()) { 2467 __ bind(&slow);
2450 // If there is a call target cache, mark it megamorphic in the 2468 if (RecordCallTarget()) {
2451 // non-function case. MegamorphicSentinel is an immortal immovable 2469 // If there is a call target cache, mark it megamorphic in the
2452 // object (undefined) so no write barrier is needed. 2470 // non-function case. MegamorphicSentinel is an immortal immovable
2453 __ mov(FieldOperand(ebx, Cell::kValueOffset), 2471 // object (undefined) so no write barrier is needed.
2454 Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); 2472 __ mov(FieldOperand(ebx, Cell::kValueOffset),
2455 } 2473 Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate)));
2456 // Check for function proxy. 2474 }
2457 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); 2475 // Check for function proxy.
2458 __ j(not_equal, &non_function); 2476 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
2459 __ pop(ecx); 2477 __ j(not_equal, &non_function);
2460 __ push(edi); // put proxy as additional argument under return address 2478 __ pop(ecx);
2461 __ push(ecx); 2479 __ push(edi); // put proxy as additional argument under return address
2462 __ Set(eax, Immediate(argc_ + 1)); 2480 __ push(ecx);
2463 __ Set(ebx, Immediate(0)); 2481 __ Set(eax, Immediate(argc_ + 1));
2464 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); 2482 __ Set(ebx, Immediate(0));
2465 { 2483 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
2484 {
2485 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
2486 __ jmp(adaptor, RelocInfo::CODE_TARGET);
2487 }
2488
2489 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
2490 // of the original receiver from the call site).
2491 __ bind(&non_function);
2492 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi);
2493 __ Set(eax, Immediate(argc_));
2494 __ Set(ebx, Immediate(0));
2495 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
2466 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); 2496 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
2467 __ jmp(adaptor, RelocInfo::CODE_TARGET); 2497 __ jmp(adaptor, RelocInfo::CODE_TARGET);
2468 } 2498 }
2469 2499
2470 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead 2500 if (CallAsMethod()) {
2471 // of the original receiver from the call site). 2501 __ bind(&wrap);
2472 __ bind(&non_function); 2502 // Wrap the receiver and patch it back onto the stack.
2473 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); 2503 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
2474 __ Set(eax, Immediate(argc_)); 2504 __ push(edi);
2475 __ Set(ebx, Immediate(0)); 2505 __ push(eax);
2476 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); 2506 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
2477 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); 2507 __ pop(edi);
2478 __ jmp(adaptor, RelocInfo::CODE_TARGET); 2508 }
2509 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), eax);
2510 __ jmp(&cont);
2511 }
2479 } 2512 }
2480 2513
2481 2514
2482 void CallConstructStub::Generate(MacroAssembler* masm) { 2515 void CallConstructStub::Generate(MacroAssembler* masm) {
2483 // eax : number of arguments 2516 // eax : number of arguments
2484 // ebx : cache cell for call target 2517 // ebx : cache cell for call target
2485 // edi : constructor function 2518 // edi : constructor function
2486 Label slow, non_function_call; 2519 Label slow, non_function_call;
2487 2520
2488 // Check that function is not a smi. 2521 // Check that function is not a smi.
(...skipping 2389 matching lines...) Expand 10 before | Expand all | Expand 10 after
4878 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); 4911 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
4879 __ pop(ecx); 4912 __ pop(ecx);
4880 int additional_offset = function_mode_ == JS_FUNCTION_STUB_MODE 4913 int additional_offset = function_mode_ == JS_FUNCTION_STUB_MODE
4881 ? kPointerSize 4914 ? kPointerSize
4882 : 0; 4915 : 0;
4883 __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset)); 4916 __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset));
4884 __ jmp(ecx); // Return to IC Miss stub, continuation still on stack. 4917 __ jmp(ecx); // Return to IC Miss stub, continuation still on stack.
4885 } 4918 }
4886 4919
4887 4920
4888 void StubFailureTailCallTrampolineStub::Generate(MacroAssembler* masm) {
4889 CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
4890 __ call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
4891 __ mov(edi, eax);
4892 int parameter_count_offset =
4893 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
4894 __ mov(eax, MemOperand(ebp, parameter_count_offset));
4895 // The parameter count above includes the receiver for the arguments passed to
4896 // the deoptimization handler. Subtract the receiver for the parameter count
4897 // for the call.
4898 __ sub(eax, Immediate(1));
4899 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
4900 ParameterCount argument_count(eax);
4901 __ InvokeFunction(edi, argument_count, JUMP_FUNCTION, NullCallWrapper());
4902 }
4903
4904
4905 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { 4921 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
4906 if (masm->isolate()->function_entry_hook() != NULL) { 4922 if (masm->isolate()->function_entry_hook() != NULL) {
4907 ProfileEntryHookStub stub; 4923 ProfileEntryHookStub stub;
4908 masm->CallStub(&stub); 4924 masm->CallStub(&stub);
4909 } 4925 }
4910 } 4926 }
4911 4927
4912 4928
4913 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { 4929 void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
4914 // Save volatile registers. 4930 // Save volatile registers.
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
5414 Operand(ebp, 7 * kPointerSize), 5430 Operand(ebp, 7 * kPointerSize),
5415 NULL); 5431 NULL);
5416 } 5432 }
5417 5433
5418 5434
5419 #undef __ 5435 #undef __
5420 5436
5421 } } // namespace v8::internal 5437 } } // namespace v8::internal
5422 5438
5423 #endif // V8_TARGET_ARCH_IA32 5439 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698