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

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 4100005: Version 2.5.2 (Closed)
Patch Set: Created 10 years, 1 month 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 | « src/x64/macro-assembler-x64.h ('k') | src/x64/regexp-macro-assembler-x64.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 int3(); 308 int3();
309 } 309 }
310 310
311 311
312 void MacroAssembler::CallStub(CodeStub* stub) { 312 void MacroAssembler::CallStub(CodeStub* stub) {
313 ASSERT(allow_stub_calls()); // calls are not allowed in some stubs 313 ASSERT(allow_stub_calls()); // calls are not allowed in some stubs
314 Call(stub->GetCode(), RelocInfo::CODE_TARGET); 314 Call(stub->GetCode(), RelocInfo::CODE_TARGET);
315 } 315 }
316 316
317 317
318 Object* MacroAssembler::TryCallStub(CodeStub* stub) { 318 MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub) {
319 ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs. 319 ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
320 Object* result = stub->TryGetCode(); 320 MaybeObject* result = stub->TryGetCode();
321 if (!result->IsFailure()) { 321 if (!result->IsFailure()) {
322 call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET); 322 call(Handle<Code>(Code::cast(result->ToObjectUnchecked())),
323 RelocInfo::CODE_TARGET);
323 } 324 }
324 return result; 325 return result;
325 } 326 }
326 327
327 328
328 void MacroAssembler::TailCallStub(CodeStub* stub) { 329 void MacroAssembler::TailCallStub(CodeStub* stub) {
329 ASSERT(allow_stub_calls()); // calls are not allowed in some stubs 330 ASSERT(allow_stub_calls()); // calls are not allowed in some stubs
330 Jump(stub->GetCode(), RelocInfo::CODE_TARGET); 331 Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
331 } 332 }
332 333
333 334
334 Object* MacroAssembler::TryTailCallStub(CodeStub* stub) { 335 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub) {
335 ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs. 336 ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
336 Object* result = stub->TryGetCode(); 337 MaybeObject* result = stub->TryGetCode();
337 if (!result->IsFailure()) { 338 if (!result->IsFailure()) {
338 jmp(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET); 339 jmp(Handle<Code>(Code::cast(result->ToObjectUnchecked())),
340 RelocInfo::CODE_TARGET);
339 } 341 }
340 return result; 342 return result;
341 } 343 }
342 344
343 345
344 void MacroAssembler::StubReturn(int argc) { 346 void MacroAssembler::StubReturn(int argc) {
345 ASSERT(argc >= 1 && generating_stub()); 347 ASSERT(argc >= 1 && generating_stub());
346 ret((argc - 1) * kPointerSize); 348 ret((argc - 1) * kPointerSize);
347 } 349 }
348 350
(...skipping 23 matching lines...) Expand all
372 // there is no difference in using either key. 374 // there is no difference in using either key.
373 Integer32ToSmi(index, hash); 375 Integer32ToSmi(index, hash);
374 } 376 }
375 377
376 378
377 void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) { 379 void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) {
378 CallRuntime(Runtime::FunctionForId(id), num_arguments); 380 CallRuntime(Runtime::FunctionForId(id), num_arguments);
379 } 381 }
380 382
381 383
382 Object* MacroAssembler::TryCallRuntime(Runtime::FunctionId id, 384 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id,
383 int num_arguments) { 385 int num_arguments) {
384 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments); 386 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments);
385 } 387 }
386 388
387 389
388 void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) { 390 void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
389 // If the expected number of arguments of the runtime function is 391 // If the expected number of arguments of the runtime function is
390 // constant, we check that the actual number of arguments match the 392 // constant, we check that the actual number of arguments match the
391 // expectation. 393 // expectation.
392 if (f->nargs >= 0 && f->nargs != num_arguments) { 394 if (f->nargs >= 0 && f->nargs != num_arguments) {
393 IllegalOperation(num_arguments); 395 IllegalOperation(num_arguments);
394 return; 396 return;
395 } 397 }
396 398
397 // TODO(1236192): Most runtime routines don't need the number of 399 // TODO(1236192): Most runtime routines don't need the number of
398 // arguments passed in because it is constant. At some point we 400 // arguments passed in because it is constant. At some point we
399 // should remove this need and make the runtime routine entry code 401 // should remove this need and make the runtime routine entry code
400 // smarter. 402 // smarter.
401 Set(rax, num_arguments); 403 Set(rax, num_arguments);
402 movq(rbx, ExternalReference(f)); 404 movq(rbx, ExternalReference(f));
403 CEntryStub ces(f->result_size); 405 CEntryStub ces(f->result_size);
404 CallStub(&ces); 406 CallStub(&ces);
405 } 407 }
406 408
407 409
408 Object* MacroAssembler::TryCallRuntime(Runtime::Function* f, 410 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::Function* f,
409 int num_arguments) { 411 int num_arguments) {
410 if (f->nargs >= 0 && f->nargs != num_arguments) { 412 if (f->nargs >= 0 && f->nargs != num_arguments) {
411 IllegalOperation(num_arguments); 413 IllegalOperation(num_arguments);
412 // Since we did not call the stub, there was no allocation failure. 414 // Since we did not call the stub, there was no allocation failure.
413 // Return some non-failure object. 415 // Return some non-failure object.
414 return Heap::undefined_value(); 416 return Heap::undefined_value();
415 } 417 }
416 418
417 // TODO(1236192): Most runtime routines don't need the number of 419 // TODO(1236192): Most runtime routines don't need the number of
418 // arguments passed in because it is constant. At some point we 420 // arguments passed in because it is constant. At some point we
419 // should remove this need and make the runtime routine entry code 421 // should remove this need and make the runtime routine entry code
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 464
463 465
464 static int Offset(ExternalReference ref0, ExternalReference ref1) { 466 static int Offset(ExternalReference ref0, ExternalReference ref1) {
465 int64_t offset = (ref0.address() - ref1.address()); 467 int64_t offset = (ref0.address() - ref1.address());
466 // Check that fits into int. 468 // Check that fits into int.
467 ASSERT(static_cast<int>(offset) == offset); 469 ASSERT(static_cast<int>(offset) == offset);
468 return static_cast<int>(offset); 470 return static_cast<int>(offset);
469 } 471 }
470 472
471 473
472 void MacroAssembler::PushHandleScope(Register scratch) { 474 void MacroAssembler::PrepareCallApiFunction(int stack_space) {
473 ExternalReference extensions_address = 475 EnterApiExitFrame(stack_space, 0);
474 ExternalReference::handle_scope_extensions_address();
475 const int kExtensionsOffset = 0;
476 const int kNextOffset = Offset(
477 ExternalReference::handle_scope_next_address(),
478 extensions_address);
479 const int kLimitOffset = Offset(
480 ExternalReference::handle_scope_limit_address(),
481 extensions_address);
482
483 // Push the number of extensions, smi-tagged so the gc will ignore it.
484 movq(kScratchRegister, extensions_address);
485 movq(scratch, Operand(kScratchRegister, kExtensionsOffset));
486 movq(Operand(kScratchRegister, kExtensionsOffset), Immediate(0));
487 Integer32ToSmi(scratch, scratch);
488 push(scratch);
489 // Push next and limit pointers which will be wordsize aligned and
490 // hence automatically smi tagged.
491 push(Operand(kScratchRegister, kNextOffset));
492 push(Operand(kScratchRegister, kLimitOffset));
493 } 476 }
494 477
495 478
496 Object* MacroAssembler::PopHandleScopeHelper(Register saved, 479 void MacroAssembler::CallApiFunctionAndReturn(ApiFunction* function) {
497 Register scratch, 480 Label empty_result;
498 bool gc_allowed) { 481 Label prologue;
499 ExternalReference extensions_address = 482 Label promote_scheduled_exception;
500 ExternalReference::handle_scope_extensions_address(); 483 Label delete_allocated_handles;
501 const int kExtensionsOffset = 0; 484 Label leave_exit_frame;
502 const int kNextOffset = Offset( 485 Label write_back;
503 ExternalReference::handle_scope_next_address(), 486
504 extensions_address); 487 ExternalReference next_address =
488 ExternalReference::handle_scope_next_address();
489 const int kNextOffset = 0;
505 const int kLimitOffset = Offset( 490 const int kLimitOffset = Offset(
506 ExternalReference::handle_scope_limit_address(), 491 ExternalReference::handle_scope_limit_address(),
507 extensions_address); 492 next_address);
493 const int kLevelOffset = Offset(
494 ExternalReference::handle_scope_level_address(),
495 next_address);
496 ExternalReference scheduled_exception_address =
497 ExternalReference::scheduled_exception_address();
508 498
509 Object* result = NULL; 499 // Allocate HandleScope in callee-save registers.
510 Label write_back; 500 Register prev_next_address_reg = r14;
511 movq(kScratchRegister, extensions_address); 501 Register prev_limit_reg = rbx;
512 cmpq(Operand(kScratchRegister, kExtensionsOffset), Immediate(0)); 502 Register base_reg = kSmiConstantRegister;
513 j(equal, &write_back); 503 movq(base_reg, next_address);
514 push(saved); 504 movq(prev_next_address_reg, Operand(base_reg, kNextOffset));
515 if (gc_allowed) { 505 movq(prev_limit_reg, Operand(base_reg, kLimitOffset));
516 CallRuntime(Runtime::kDeleteHandleScopeExtensions, 0); 506 addl(Operand(base_reg, kLevelOffset), Immediate(1));
517 } else { 507 // Call the api function!
518 result = TryCallRuntime(Runtime::kDeleteHandleScopeExtensions, 0); 508 movq(rax,
519 if (result->IsFailure()) return result; 509 reinterpret_cast<int64_t>(function->address()),
520 } 510 RelocInfo::RUNTIME_ENTRY);
521 pop(saved); 511 call(rax);
522 movq(kScratchRegister, extensions_address);
523 512
524 bind(&write_back); 513 #ifdef _WIN64
525 pop(Operand(kScratchRegister, kLimitOffset)); 514 // rax keeps a pointer to v8::Handle, unpack it.
526 pop(Operand(kScratchRegister, kNextOffset)); 515 movq(rax, Operand(rax, 0));
527 pop(scratch); 516 #endif
528 SmiToInteger32(scratch, scratch); 517 // Check if the result handle holds 0.
529 movq(Operand(kScratchRegister, kExtensionsOffset), scratch); 518 testq(rax, rax);
519 j(zero, &empty_result);
520 // It was non-zero. Dereference to get the result value.
521 movq(rax, Operand(rax, 0));
522 bind(&prologue);
530 523
531 return result; 524 // No more valid handles (the result handle was the last one). Restore
525 // previous handle scope.
526 subl(Operand(base_reg, kLevelOffset), Immediate(1));
527 movq(Operand(base_reg, kNextOffset), prev_next_address_reg);
528 cmpq(prev_limit_reg, Operand(base_reg, kLimitOffset));
529 j(not_equal, &delete_allocated_handles);
530 bind(&leave_exit_frame);
531 InitializeSmiConstantRegister();
532
533 // Check if the function scheduled an exception.
534 movq(rsi, scheduled_exception_address);
535 Cmp(Operand(rsi, 0), Factory::the_hole_value());
536 j(not_equal, &promote_scheduled_exception);
537
538 LeaveExitFrame();
539 ret(0);
540
541 bind(&promote_scheduled_exception);
542 TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
543
544 bind(&empty_result);
545 // It was zero; the result is undefined.
546 Move(rax, Factory::undefined_value());
547 jmp(&prologue);
548
549 // HandleScope limit has changed. Delete allocated extensions.
550 bind(&delete_allocated_handles);
551 movq(Operand(base_reg, kLimitOffset), prev_limit_reg);
552 movq(prev_limit_reg, rax);
553 movq(rax, ExternalReference::delete_handle_scope_extensions());
554 call(rax);
555 movq(rax, prev_limit_reg);
556 jmp(&leave_exit_frame);
532 } 557 }
533 558
534 559
535 void MacroAssembler::PopHandleScope(Register saved, Register scratch) {
536 PopHandleScopeHelper(saved, scratch, true);
537 }
538
539
540 Object* MacroAssembler::TryPopHandleScope(Register saved, Register scratch) {
541 return PopHandleScopeHelper(saved, scratch, false);
542 }
543
544
545 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext, 560 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext,
546 int result_size) { 561 int result_size) {
547 // Set the entry point and jump to the C entry runtime stub. 562 // Set the entry point and jump to the C entry runtime stub.
548 movq(rbx, ext); 563 movq(rbx, ext);
549 CEntryStub ces(result_size); 564 CEntryStub ces(result_size);
550 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 565 jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
551 } 566 }
552 567
553 568
554 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) { 569 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1884 } 1899 }
1885 } 1900 }
1886 1901
1887 1902
1888 void MacroAssembler::AllocateInNewSpace(int object_size, 1903 void MacroAssembler::AllocateInNewSpace(int object_size,
1889 Register result, 1904 Register result,
1890 Register result_end, 1905 Register result_end,
1891 Register scratch, 1906 Register scratch,
1892 Label* gc_required, 1907 Label* gc_required,
1893 AllocationFlags flags) { 1908 AllocationFlags flags) {
1909 if (!FLAG_inline_new) {
1910 if (FLAG_debug_code) {
1911 // Trash the registers to simulate an allocation failure.
1912 movl(result, Immediate(0x7091));
1913 if (result_end.is_valid()) {
1914 movl(result_end, Immediate(0x7191));
1915 }
1916 if (scratch.is_valid()) {
1917 movl(scratch, Immediate(0x7291));
1918 }
1919 }
1920 jmp(gc_required);
1921 return;
1922 }
1894 ASSERT(!result.is(result_end)); 1923 ASSERT(!result.is(result_end));
1895 1924
1896 // Load address of new object into result. 1925 // Load address of new object into result.
1897 LoadAllocationTopHelper(result, result_end, scratch, flags); 1926 LoadAllocationTopHelper(result, result_end, scratch, flags);
1898 1927
1899 // Calculate new top and bail out if new space is exhausted. 1928 // Calculate new top and bail out if new space is exhausted.
1900 ExternalReference new_space_allocation_limit = 1929 ExternalReference new_space_allocation_limit =
1901 ExternalReference::new_space_allocation_limit_address(); 1930 ExternalReference::new_space_allocation_limit_address();
1902 1931
1903 Register top_reg = result_end.is_valid() ? result_end : result; 1932 Register top_reg = result_end.is_valid() ? result_end : result;
(...skipping 24 matching lines...) Expand all
1928 1957
1929 1958
1930 void MacroAssembler::AllocateInNewSpace(int header_size, 1959 void MacroAssembler::AllocateInNewSpace(int header_size,
1931 ScaleFactor element_size, 1960 ScaleFactor element_size,
1932 Register element_count, 1961 Register element_count,
1933 Register result, 1962 Register result,
1934 Register result_end, 1963 Register result_end,
1935 Register scratch, 1964 Register scratch,
1936 Label* gc_required, 1965 Label* gc_required,
1937 AllocationFlags flags) { 1966 AllocationFlags flags) {
1967 if (!FLAG_inline_new) {
1968 if (FLAG_debug_code) {
1969 // Trash the registers to simulate an allocation failure.
1970 movl(result, Immediate(0x7091));
1971 movl(result_end, Immediate(0x7191));
1972 if (scratch.is_valid()) {
1973 movl(scratch, Immediate(0x7291));
1974 }
1975 // Register element_count is not modified by the function.
1976 }
1977 jmp(gc_required);
1978 return;
1979 }
1938 ASSERT(!result.is(result_end)); 1980 ASSERT(!result.is(result_end));
1939 1981
1940 // Load address of new object into result. 1982 // Load address of new object into result.
1941 LoadAllocationTopHelper(result, result_end, scratch, flags); 1983 LoadAllocationTopHelper(result, result_end, scratch, flags);
1942 1984
1943 // Calculate new top and bail out if new space is exhausted. 1985 // Calculate new top and bail out if new space is exhausted.
1944 ExternalReference new_space_allocation_limit = 1986 ExternalReference new_space_allocation_limit =
1945 ExternalReference::new_space_allocation_limit_address(); 1987 ExternalReference::new_space_allocation_limit_address();
1946 lea(result_end, Operand(result, element_count, element_size, header_size)); 1988 lea(result_end, Operand(result, element_count, element_size, header_size));
1947 movq(kScratchRegister, new_space_allocation_limit); 1989 movq(kScratchRegister, new_space_allocation_limit);
1948 cmpq(result_end, Operand(kScratchRegister, 0)); 1990 cmpq(result_end, Operand(kScratchRegister, 0));
1949 j(above, gc_required); 1991 j(above, gc_required);
1950 1992
1951 // Update allocation top. 1993 // Update allocation top.
1952 UpdateAllocationTopHelper(result_end, scratch); 1994 UpdateAllocationTopHelper(result_end, scratch);
1953 1995
1954 // Tag the result if requested. 1996 // Tag the result if requested.
1955 if ((flags & TAG_OBJECT) != 0) { 1997 if ((flags & TAG_OBJECT) != 0) {
1956 addq(result, Immediate(kHeapObjectTag)); 1998 addq(result, Immediate(kHeapObjectTag));
1957 } 1999 }
1958 } 2000 }
1959 2001
1960 2002
1961 void MacroAssembler::AllocateInNewSpace(Register object_size, 2003 void MacroAssembler::AllocateInNewSpace(Register object_size,
1962 Register result, 2004 Register result,
1963 Register result_end, 2005 Register result_end,
1964 Register scratch, 2006 Register scratch,
1965 Label* gc_required, 2007 Label* gc_required,
1966 AllocationFlags flags) { 2008 AllocationFlags flags) {
2009 if (!FLAG_inline_new) {
2010 if (FLAG_debug_code) {
2011 // Trash the registers to simulate an allocation failure.
2012 movl(result, Immediate(0x7091));
2013 movl(result_end, Immediate(0x7191));
2014 if (scratch.is_valid()) {
2015 movl(scratch, Immediate(0x7291));
2016 }
2017 // object_size is left unchanged by this function.
2018 }
2019 jmp(gc_required);
2020 return;
2021 }
2022 ASSERT(!result.is(result_end));
2023
1967 // Load address of new object into result. 2024 // Load address of new object into result.
1968 LoadAllocationTopHelper(result, result_end, scratch, flags); 2025 LoadAllocationTopHelper(result, result_end, scratch, flags);
1969 2026
1970 // Calculate new top and bail out if new space is exhausted. 2027 // Calculate new top and bail out if new space is exhausted.
1971 ExternalReference new_space_allocation_limit = 2028 ExternalReference new_space_allocation_limit =
1972 ExternalReference::new_space_allocation_limit_address(); 2029 ExternalReference::new_space_allocation_limit_address();
1973 if (!object_size.is(result_end)) { 2030 if (!object_size.is(result_end)) {
1974 movq(result_end, object_size); 2031 movq(result_end, object_size);
1975 } 2032 }
1976 addq(result_end, result); 2033 addq(result_end, result);
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
2223 CPU::FlushICache(address_, size_); 2280 CPU::FlushICache(address_, size_);
2224 2281
2225 // Check that the code was patched as expected. 2282 // Check that the code was patched as expected.
2226 ASSERT(masm_.pc_ == address_ + size_); 2283 ASSERT(masm_.pc_ == address_ + size_);
2227 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 2284 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
2228 } 2285 }
2229 2286
2230 } } // namespace v8::internal 2287 } } // namespace v8::internal
2231 2288
2232 #endif // V8_TARGET_ARCH_X64 2289 #endif // V8_TARGET_ARCH_X64
OLDNEW
« 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