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

Unified Diff: src/x64/macro-assembler-x64.cc

Issue 4100005: Version 2.5.2 (Closed)
Patch Set: Created 10 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/regexp-macro-assembler-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/macro-assembler-x64.cc
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 2c946f56b9fc4c13c15e7d16ea59c76aeabf67f1..293d8a5633f6ed33e40a47dc864cc305cf1654c1 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -315,11 +315,12 @@ void MacroAssembler::CallStub(CodeStub* stub) {
}
-Object* MacroAssembler::TryCallStub(CodeStub* stub) {
+MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub) {
ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
- Object* result = stub->TryGetCode();
+ MaybeObject* result = stub->TryGetCode();
if (!result->IsFailure()) {
- call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET);
+ call(Handle<Code>(Code::cast(result->ToObjectUnchecked())),
+ RelocInfo::CODE_TARGET);
}
return result;
}
@@ -331,11 +332,12 @@ void MacroAssembler::TailCallStub(CodeStub* stub) {
}
-Object* MacroAssembler::TryTailCallStub(CodeStub* stub) {
+MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub) {
ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
- Object* result = stub->TryGetCode();
+ MaybeObject* result = stub->TryGetCode();
if (!result->IsFailure()) {
- jmp(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET);
+ jmp(Handle<Code>(Code::cast(result->ToObjectUnchecked())),
+ RelocInfo::CODE_TARGET);
}
return result;
}
@@ -379,8 +381,8 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) {
}
-Object* MacroAssembler::TryCallRuntime(Runtime::FunctionId id,
- int num_arguments) {
+MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id,
+ int num_arguments) {
return TryCallRuntime(Runtime::FunctionForId(id), num_arguments);
}
@@ -405,8 +407,8 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
}
-Object* MacroAssembler::TryCallRuntime(Runtime::Function* f,
- int num_arguments) {
+MaybeObject* MacroAssembler::TryCallRuntime(Runtime::Function* f,
+ int num_arguments) {
if (f->nargs >= 0 && f->nargs != num_arguments) {
IllegalOperation(num_arguments);
// Since we did not call the stub, there was no allocation failure.
@@ -469,76 +471,89 @@ static int Offset(ExternalReference ref0, ExternalReference ref1) {
}
-void MacroAssembler::PushHandleScope(Register scratch) {
- ExternalReference extensions_address =
- ExternalReference::handle_scope_extensions_address();
- const int kExtensionsOffset = 0;
- const int kNextOffset = Offset(
- ExternalReference::handle_scope_next_address(),
- extensions_address);
- const int kLimitOffset = Offset(
- ExternalReference::handle_scope_limit_address(),
- extensions_address);
-
- // Push the number of extensions, smi-tagged so the gc will ignore it.
- movq(kScratchRegister, extensions_address);
- movq(scratch, Operand(kScratchRegister, kExtensionsOffset));
- movq(Operand(kScratchRegister, kExtensionsOffset), Immediate(0));
- Integer32ToSmi(scratch, scratch);
- push(scratch);
- // Push next and limit pointers which will be wordsize aligned and
- // hence automatically smi tagged.
- push(Operand(kScratchRegister, kNextOffset));
- push(Operand(kScratchRegister, kLimitOffset));
+void MacroAssembler::PrepareCallApiFunction(int stack_space) {
+ EnterApiExitFrame(stack_space, 0);
}
-Object* MacroAssembler::PopHandleScopeHelper(Register saved,
- Register scratch,
- bool gc_allowed) {
- ExternalReference extensions_address =
- ExternalReference::handle_scope_extensions_address();
- const int kExtensionsOffset = 0;
- const int kNextOffset = Offset(
- ExternalReference::handle_scope_next_address(),
- extensions_address);
- const int kLimitOffset = Offset(
- ExternalReference::handle_scope_limit_address(),
- extensions_address);
-
- Object* result = NULL;
+void MacroAssembler::CallApiFunctionAndReturn(ApiFunction* function) {
+ Label empty_result;
+ Label prologue;
+ Label promote_scheduled_exception;
+ Label delete_allocated_handles;
+ Label leave_exit_frame;
Label write_back;
- movq(kScratchRegister, extensions_address);
- cmpq(Operand(kScratchRegister, kExtensionsOffset), Immediate(0));
- j(equal, &write_back);
- push(saved);
- if (gc_allowed) {
- CallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
- } else {
- result = TryCallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
- if (result->IsFailure()) return result;
- }
- pop(saved);
- movq(kScratchRegister, extensions_address);
-
- bind(&write_back);
- pop(Operand(kScratchRegister, kLimitOffset));
- pop(Operand(kScratchRegister, kNextOffset));
- pop(scratch);
- SmiToInteger32(scratch, scratch);
- movq(Operand(kScratchRegister, kExtensionsOffset), scratch);
- return result;
-}
+ ExternalReference next_address =
+ ExternalReference::handle_scope_next_address();
+ const int kNextOffset = 0;
+ const int kLimitOffset = Offset(
+ ExternalReference::handle_scope_limit_address(),
+ next_address);
+ const int kLevelOffset = Offset(
+ ExternalReference::handle_scope_level_address(),
+ next_address);
+ ExternalReference scheduled_exception_address =
+ ExternalReference::scheduled_exception_address();
+
+ // Allocate HandleScope in callee-save registers.
+ Register prev_next_address_reg = r14;
+ Register prev_limit_reg = rbx;
+ Register base_reg = kSmiConstantRegister;
+ movq(base_reg, next_address);
+ movq(prev_next_address_reg, Operand(base_reg, kNextOffset));
+ movq(prev_limit_reg, Operand(base_reg, kLimitOffset));
+ addl(Operand(base_reg, kLevelOffset), Immediate(1));
+ // Call the api function!
+ movq(rax,
+ reinterpret_cast<int64_t>(function->address()),
+ RelocInfo::RUNTIME_ENTRY);
+ call(rax);
+#ifdef _WIN64
+ // rax keeps a pointer to v8::Handle, unpack it.
+ movq(rax, Operand(rax, 0));
+#endif
+ // Check if the result handle holds 0.
+ testq(rax, rax);
+ j(zero, &empty_result);
+ // It was non-zero. Dereference to get the result value.
+ movq(rax, Operand(rax, 0));
+ bind(&prologue);
+
+ // No more valid handles (the result handle was the last one). Restore
+ // previous handle scope.
+ subl(Operand(base_reg, kLevelOffset), Immediate(1));
+ movq(Operand(base_reg, kNextOffset), prev_next_address_reg);
+ cmpq(prev_limit_reg, Operand(base_reg, kLimitOffset));
+ j(not_equal, &delete_allocated_handles);
+ bind(&leave_exit_frame);
+ InitializeSmiConstantRegister();
+
+ // Check if the function scheduled an exception.
+ movq(rsi, scheduled_exception_address);
+ Cmp(Operand(rsi, 0), Factory::the_hole_value());
+ j(not_equal, &promote_scheduled_exception);
+
+ LeaveExitFrame();
+ ret(0);
-void MacroAssembler::PopHandleScope(Register saved, Register scratch) {
- PopHandleScopeHelper(saved, scratch, true);
-}
+ bind(&promote_scheduled_exception);
+ TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
+ bind(&empty_result);
+ // It was zero; the result is undefined.
+ Move(rax, Factory::undefined_value());
+ jmp(&prologue);
-Object* MacroAssembler::TryPopHandleScope(Register saved, Register scratch) {
- return PopHandleScopeHelper(saved, scratch, false);
+ // HandleScope limit has changed. Delete allocated extensions.
+ bind(&delete_allocated_handles);
+ movq(Operand(base_reg, kLimitOffset), prev_limit_reg);
+ movq(prev_limit_reg, rax);
+ movq(rax, ExternalReference::delete_handle_scope_extensions());
+ call(rax);
+ movq(rax, prev_limit_reg);
+ jmp(&leave_exit_frame);
}
@@ -1891,6 +1906,20 @@ void MacroAssembler::AllocateInNewSpace(int object_size,
Register scratch,
Label* gc_required,
AllocationFlags flags) {
+ if (!FLAG_inline_new) {
+ if (FLAG_debug_code) {
+ // Trash the registers to simulate an allocation failure.
+ movl(result, Immediate(0x7091));
+ if (result_end.is_valid()) {
+ movl(result_end, Immediate(0x7191));
+ }
+ if (scratch.is_valid()) {
+ movl(scratch, Immediate(0x7291));
+ }
+ }
+ jmp(gc_required);
+ return;
+ }
ASSERT(!result.is(result_end));
// Load address of new object into result.
@@ -1935,6 +1964,19 @@ void MacroAssembler::AllocateInNewSpace(int header_size,
Register scratch,
Label* gc_required,
AllocationFlags flags) {
+ if (!FLAG_inline_new) {
+ if (FLAG_debug_code) {
+ // Trash the registers to simulate an allocation failure.
+ movl(result, Immediate(0x7091));
+ movl(result_end, Immediate(0x7191));
+ if (scratch.is_valid()) {
+ movl(scratch, Immediate(0x7291));
+ }
+ // Register element_count is not modified by the function.
+ }
+ jmp(gc_required);
+ return;
+ }
ASSERT(!result.is(result_end));
// Load address of new object into result.
@@ -1964,6 +2006,21 @@ void MacroAssembler::AllocateInNewSpace(Register object_size,
Register scratch,
Label* gc_required,
AllocationFlags flags) {
+ if (!FLAG_inline_new) {
+ if (FLAG_debug_code) {
+ // Trash the registers to simulate an allocation failure.
+ movl(result, Immediate(0x7091));
+ movl(result_end, Immediate(0x7191));
+ if (scratch.is_valid()) {
+ movl(scratch, Immediate(0x7291));
+ }
+ // object_size is left unchanged by this function.
+ }
+ jmp(gc_required);
+ return;
+ }
+ ASSERT(!result.is(result_end));
+
// Load address of new object into result.
LoadAllocationTopHelper(result, result_end, scratch, flags);
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/regexp-macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698