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

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

Issue 861053002: X87: move CallApiFunctionAndReturn to code-stubs-* (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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
« no previous file with comments | « no previous file | src/x87/macro-assembler-x87.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 "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X87 7 #if V8_TARGET_ARCH_X87
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 4323 matching lines...) Expand 10 before | Expand all | Expand 10 after
4334 Label fast_elements_case; 4334 Label fast_elements_case;
4335 __ cmp(ecx, Immediate(FAST_ELEMENTS)); 4335 __ cmp(ecx, Immediate(FAST_ELEMENTS));
4336 __ j(equal, &fast_elements_case); 4336 __ j(equal, &fast_elements_case);
4337 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 4337 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
4338 4338
4339 __ bind(&fast_elements_case); 4339 __ bind(&fast_elements_case);
4340 GenerateCase(masm, FAST_ELEMENTS); 4340 GenerateCase(masm, FAST_ELEMENTS);
4341 } 4341 }
4342 4342
4343 4343
4344 // Generates an Operand for saving parameters after PrepareCallApiFunction.
4345 static Operand ApiParameterOperand(int index) {
4346 return Operand(esp, index * kPointerSize);
4347 }
4348
4349
4350 // Prepares stack to put arguments (aligns and so on). Reserves
4351 // space for return value if needed (assumes the return value is a handle).
4352 // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
4353 // etc. Saves context (esi). If space was reserved for return value then
4354 // stores the pointer to the reserved slot into esi.
4355 static void PrepareCallApiFunction(MacroAssembler* masm, int argc) {
4356 __ EnterApiExitFrame(argc);
4357 if (__ emit_debug_code()) {
4358 __ mov(esi, Immediate(bit_cast<int32_t>(kZapValue)));
4359 }
4360 }
4361
4362
4363 // Calls an API function. Allocates HandleScope, extracts returned value
4364 // from handle and propagates exceptions. Clobbers ebx, edi and
4365 // caller-save registers. Restores context. On return removes
4366 // stack_space * kPointerSize (GCed).
4367 static void CallApiFunctionAndReturn(MacroAssembler* masm,
4368 Register function_address,
4369 ExternalReference thunk_ref,
4370 Operand thunk_last_arg, int stack_space,
4371 Operand* stack_space_operand,
4372 Operand return_value_operand,
4373 Operand* context_restore_operand) {
4374 Isolate* isolate = masm->isolate();
4375
4376 ExternalReference next_address =
4377 ExternalReference::handle_scope_next_address(isolate);
4378 ExternalReference limit_address =
4379 ExternalReference::handle_scope_limit_address(isolate);
4380 ExternalReference level_address =
4381 ExternalReference::handle_scope_level_address(isolate);
4382
4383 DCHECK(edx.is(function_address));
4384 // Allocate HandleScope in callee-save registers.
4385 __ mov(ebx, Operand::StaticVariable(next_address));
4386 __ mov(edi, Operand::StaticVariable(limit_address));
4387 __ add(Operand::StaticVariable(level_address), Immediate(1));
4388
4389 if (FLAG_log_timer_events) {
4390 FrameScope frame(masm, StackFrame::MANUAL);
4391 __ PushSafepointRegisters();
4392 __ PrepareCallCFunction(1, eax);
4393 __ mov(Operand(esp, 0),
4394 Immediate(ExternalReference::isolate_address(isolate)));
4395 __ CallCFunction(ExternalReference::log_enter_external_function(isolate),
4396 1);
4397 __ PopSafepointRegisters();
4398 }
4399
4400
4401 Label profiler_disabled;
4402 Label end_profiler_check;
4403 __ mov(eax, Immediate(ExternalReference::is_profiling_address(isolate)));
4404 __ cmpb(Operand(eax, 0), 0);
4405 __ j(zero, &profiler_disabled);
4406
4407 // Additional parameter is the address of the actual getter function.
4408 __ mov(thunk_last_arg, function_address);
4409 // Call the api function.
4410 __ mov(eax, Immediate(thunk_ref));
4411 __ call(eax);
4412 __ jmp(&end_profiler_check);
4413
4414 __ bind(&profiler_disabled);
4415 // Call the api function.
4416 __ call(function_address);
4417 __ bind(&end_profiler_check);
4418
4419 if (FLAG_log_timer_events) {
4420 FrameScope frame(masm, StackFrame::MANUAL);
4421 __ PushSafepointRegisters();
4422 __ PrepareCallCFunction(1, eax);
4423 __ mov(Operand(esp, 0),
4424 Immediate(ExternalReference::isolate_address(isolate)));
4425 __ CallCFunction(ExternalReference::log_leave_external_function(isolate),
4426 1);
4427 __ PopSafepointRegisters();
4428 }
4429
4430 Label prologue;
4431 // Load the value from ReturnValue
4432 __ mov(eax, return_value_operand);
4433
4434 Label promote_scheduled_exception;
4435 Label exception_handled;
4436 Label delete_allocated_handles;
4437 Label leave_exit_frame;
4438
4439 __ bind(&prologue);
4440 // No more valid handles (the result handle was the last one). Restore
4441 // previous handle scope.
4442 __ mov(Operand::StaticVariable(next_address), ebx);
4443 __ sub(Operand::StaticVariable(level_address), Immediate(1));
4444 __ Assert(above_equal, kInvalidHandleScopeLevel);
4445 __ cmp(edi, Operand::StaticVariable(limit_address));
4446 __ j(not_equal, &delete_allocated_handles);
4447 __ bind(&leave_exit_frame);
4448
4449 // Check if the function scheduled an exception.
4450 ExternalReference scheduled_exception_address =
4451 ExternalReference::scheduled_exception_address(isolate);
4452 __ cmp(Operand::StaticVariable(scheduled_exception_address),
4453 Immediate(isolate->factory()->the_hole_value()));
4454 __ j(not_equal, &promote_scheduled_exception);
4455 __ bind(&exception_handled);
4456
4457 #if DEBUG
4458 // Check if the function returned a valid JavaScript value.
4459 Label ok;
4460 Register return_value = eax;
4461 Register map = ecx;
4462
4463 __ JumpIfSmi(return_value, &ok, Label::kNear);
4464 __ mov(map, FieldOperand(return_value, HeapObject::kMapOffset));
4465
4466 __ CmpInstanceType(map, LAST_NAME_TYPE);
4467 __ j(below_equal, &ok, Label::kNear);
4468
4469 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
4470 __ j(above_equal, &ok, Label::kNear);
4471
4472 __ cmp(map, isolate->factory()->heap_number_map());
4473 __ j(equal, &ok, Label::kNear);
4474
4475 __ cmp(return_value, isolate->factory()->undefined_value());
4476 __ j(equal, &ok, Label::kNear);
4477
4478 __ cmp(return_value, isolate->factory()->true_value());
4479 __ j(equal, &ok, Label::kNear);
4480
4481 __ cmp(return_value, isolate->factory()->false_value());
4482 __ j(equal, &ok, Label::kNear);
4483
4484 __ cmp(return_value, isolate->factory()->null_value());
4485 __ j(equal, &ok, Label::kNear);
4486
4487 __ Abort(kAPICallReturnedInvalidObject);
4488
4489 __ bind(&ok);
4490 #endif
4491
4492 bool restore_context = context_restore_operand != NULL;
4493 if (restore_context) {
4494 __ mov(esi, *context_restore_operand);
4495 }
4496 if (stack_space_operand != nullptr) {
4497 __ mov(ebx, *stack_space_operand);
4498 }
4499 __ LeaveApiExitFrame(!restore_context);
4500 if (stack_space_operand != nullptr) {
4501 DCHECK_EQ(0, stack_space);
4502 __ pop(ecx);
4503 __ add(esp, ebx);
4504 __ jmp(ecx);
4505 } else {
4506 __ ret(stack_space * kPointerSize);
4507 }
4508
4509 __ bind(&promote_scheduled_exception);
4510 {
4511 FrameScope frame(masm, StackFrame::INTERNAL);
4512 __ CallRuntime(Runtime::kPromoteScheduledException, 0);
4513 }
4514 __ jmp(&exception_handled);
4515
4516 // HandleScope limit has changed. Delete allocated extensions.
4517 ExternalReference delete_extensions =
4518 ExternalReference::delete_handle_scope_extensions(isolate);
4519 __ bind(&delete_allocated_handles);
4520 __ mov(Operand::StaticVariable(limit_address), edi);
4521 __ mov(edi, eax);
4522 __ mov(Operand(esp, 0),
4523 Immediate(ExternalReference::isolate_address(isolate)));
4524 __ mov(eax, Immediate(delete_extensions));
4525 __ call(eax);
4526 __ mov(eax, edi);
4527 __ jmp(&leave_exit_frame);
4528 }
4529
4530
4344 static void CallApiFunctionStubHelper(MacroAssembler* masm, 4531 static void CallApiFunctionStubHelper(MacroAssembler* masm,
4345 const ParameterCount& argc, 4532 const ParameterCount& argc,
4346 bool return_first_arg, 4533 bool return_first_arg,
4347 bool call_data_undefined) { 4534 bool call_data_undefined) {
4348 // ----------- S t a t e ------------- 4535 // ----------- S t a t e -------------
4349 // -- eax : callee 4536 // -- eax : callee
4350 // -- ebx : call_data 4537 // -- ebx : call_data
4351 // -- ecx : holder 4538 // -- ecx : holder
4352 // -- edx : api_function_address 4539 // -- edx : api_function_address
4353 // -- esi : context 4540 // -- esi : context
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
4416 // API function gets reference to the v8::Arguments. If CPU profiler 4603 // API function gets reference to the v8::Arguments. If CPU profiler
4417 // is enabled wrapper function will be called and we need to pass 4604 // is enabled wrapper function will be called and we need to pass
4418 // address of the callback as additional parameter, always allocate 4605 // address of the callback as additional parameter, always allocate
4419 // space for it. 4606 // space for it.
4420 const int kApiArgc = 1 + 1; 4607 const int kApiArgc = 1 + 1;
4421 4608
4422 // Allocate the v8::Arguments structure in the arguments' space since 4609 // Allocate the v8::Arguments structure in the arguments' space since
4423 // it's not controlled by GC. 4610 // it's not controlled by GC.
4424 const int kApiStackSpace = 4; 4611 const int kApiStackSpace = 4;
4425 4612
4426 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); 4613 PrepareCallApiFunction(masm, kApiArgc + kApiStackSpace);
4427 4614
4428 // FunctionCallbackInfo::implicit_args_. 4615 // FunctionCallbackInfo::implicit_args_.
4429 __ mov(ApiParameterOperand(2), scratch); 4616 __ mov(ApiParameterOperand(2), scratch);
4430 if (argc.is_immediate()) { 4617 if (argc.is_immediate()) {
4431 __ add(scratch, 4618 __ add(scratch,
4432 Immediate((argc.immediate() + FCA::kArgsLength - 1) * kPointerSize)); 4619 Immediate((argc.immediate() + FCA::kArgsLength - 1) * kPointerSize));
4433 // FunctionCallbackInfo::values_. 4620 // FunctionCallbackInfo::values_.
4434 __ mov(ApiParameterOperand(3), scratch); 4621 __ mov(ApiParameterOperand(3), scratch);
4435 // FunctionCallbackInfo::length_. 4622 // FunctionCallbackInfo::length_.
4436 __ Move(ApiParameterOperand(4), Immediate(argc.immediate())); 4623 __ Move(ApiParameterOperand(4), Immediate(argc.immediate()));
(...skipping 29 matching lines...) Expand all
4466 return_value_offset = 2 + FCA::kReturnValueOffset; 4653 return_value_offset = 2 + FCA::kReturnValueOffset;
4467 } 4654 }
4468 Operand return_value_operand(ebp, return_value_offset * kPointerSize); 4655 Operand return_value_operand(ebp, return_value_offset * kPointerSize);
4469 int stack_space = 0; 4656 int stack_space = 0;
4470 Operand is_construct_call_operand = ApiParameterOperand(5); 4657 Operand is_construct_call_operand = ApiParameterOperand(5);
4471 Operand* stack_space_operand = &is_construct_call_operand; 4658 Operand* stack_space_operand = &is_construct_call_operand;
4472 if (argc.is_immediate()) { 4659 if (argc.is_immediate()) {
4473 stack_space = argc.immediate() + FCA::kArgsLength + 1; 4660 stack_space = argc.immediate() + FCA::kArgsLength + 1;
4474 stack_space_operand = nullptr; 4661 stack_space_operand = nullptr;
4475 } 4662 }
4476 __ CallApiFunctionAndReturn( 4663 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
4477 api_function_address, thunk_ref, ApiParameterOperand(1), stack_space, 4664 ApiParameterOperand(1), stack_space,
4478 stack_space_operand, return_value_operand, &context_restore_operand); 4665 stack_space_operand, return_value_operand,
4666 &context_restore_operand);
4479 } 4667 }
4480 4668
4481 4669
4482 void CallApiFunctionStub::Generate(MacroAssembler* masm) { 4670 void CallApiFunctionStub::Generate(MacroAssembler* masm) {
4483 // TODO(dcarney): make eax contain the function address. 4671 // TODO(dcarney): make eax contain the function address.
4484 bool call_data_undefined = this->call_data_undefined(); 4672 bool call_data_undefined = this->call_data_undefined();
4485 CallApiFunctionStubHelper(masm, ParameterCount(edi), false, 4673 CallApiFunctionStubHelper(masm, ParameterCount(edi), false,
4486 call_data_undefined); 4674 call_data_undefined);
4487 } 4675 }
4488 4676
(...skipping 23 matching lines...) Expand all
4512 // Allocate space for opional callback address parameter in case 4700 // Allocate space for opional callback address parameter in case
4513 // CPU profiler is active. 4701 // CPU profiler is active.
4514 const int kApiArgc = 2 + 1; 4702 const int kApiArgc = 2 + 1;
4515 4703
4516 Register api_function_address = edx; 4704 Register api_function_address = edx;
4517 Register scratch = ebx; 4705 Register scratch = ebx;
4518 4706
4519 // load address of name 4707 // load address of name
4520 __ lea(scratch, Operand(esp, 1 * kPointerSize)); 4708 __ lea(scratch, Operand(esp, 1 * kPointerSize));
4521 4709
4522 __ PrepareCallApiFunction(kApiArgc); 4710 PrepareCallApiFunction(masm, kApiArgc);
4523 __ mov(ApiParameterOperand(0), scratch); // name. 4711 __ mov(ApiParameterOperand(0), scratch); // name.
4524 __ add(scratch, Immediate(kPointerSize)); 4712 __ add(scratch, Immediate(kPointerSize));
4525 __ mov(ApiParameterOperand(1), scratch); // arguments pointer. 4713 __ mov(ApiParameterOperand(1), scratch); // arguments pointer.
4526 4714
4527 ExternalReference thunk_ref = 4715 ExternalReference thunk_ref =
4528 ExternalReference::invoke_accessor_getter_callback(isolate()); 4716 ExternalReference::invoke_accessor_getter_callback(isolate());
4529 4717
4530 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, 4718 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
4531 ApiParameterOperand(2), kStackSpace, nullptr, 4719 ApiParameterOperand(2), kStackSpace, nullptr,
4532 Operand(ebp, 7 * kPointerSize), NULL); 4720 Operand(ebp, 7 * kPointerSize), NULL);
4533 } 4721 }
4534 4722
4535 4723
4536 #undef __ 4724 #undef __
4537 4725
4538 } } // namespace v8::internal 4726 } } // namespace v8::internal
4539 4727
4540 #endif // V8_TARGET_ARCH_X87 4728 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | src/x87/macro-assembler-x87.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698