comparison src/os/windows/vm/os_windows.cpp @ 656:6bdd6923ba16

6541756: Reduce executable C-heap Summary: Add executable parameters to reserve_memory and commit_memory to reduce executable memory to only the Code Heap. Reviewed-by: xlu, kvn, acorn
author coleenp
date Wed, 25 Mar 2009 14:19:20 -0400
parents bd441136a5ce
children 956304450e80
comparison
equal deleted inserted replaced
655:60bfce711da4 656:6bdd6923ba16
2187 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; 2187 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2188 address addr = (address) exceptionRecord->ExceptionInformation[1]; 2188 address addr = (address) exceptionRecord->ExceptionInformation[1];
2189 if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) { 2189 if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) {
2190 addr = (address)((uintptr_t)addr & 2190 addr = (address)((uintptr_t)addr &
2191 (~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); 2191 (~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
2192 os::commit_memory( (char *)addr, thread->stack_base() - addr ); 2192 os::commit_memory((char *)addr, thread->stack_base() - addr,
2193 false );
2193 return EXCEPTION_CONTINUE_EXECUTION; 2194 return EXCEPTION_CONTINUE_EXECUTION;
2194 } 2195 }
2195 else 2196 else
2196 #endif 2197 #endif
2197 { 2198 {
2563 2564
2564 char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) { 2565 char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
2565 assert((size_t)addr % os::vm_allocation_granularity() == 0, 2566 assert((size_t)addr % os::vm_allocation_granularity() == 0,
2566 "reserve alignment"); 2567 "reserve alignment");
2567 assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size"); 2568 assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size");
2568 char* res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, 2569 char* res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);
2569 PAGE_EXECUTE_READWRITE);
2570 assert(res == NULL || addr == NULL || addr == res, 2570 assert(res == NULL || addr == NULL || addr == res,
2571 "Unexpected address from reserve."); 2571 "Unexpected address from reserve.");
2572 return res; 2572 return res;
2573 } 2573 }
2574 2574
2593 2593
2594 bool os::can_execute_large_page_memory() { 2594 bool os::can_execute_large_page_memory() {
2595 return true; 2595 return true;
2596 } 2596 }
2597 2597
2598 char* os::reserve_memory_special(size_t bytes, char* addr) { 2598 char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
2599 2599
2600 if (UseLargePagesIndividualAllocation) { 2600 if (UseLargePagesIndividualAllocation) {
2601 if (TracePageSizes && Verbose) { 2601 if (TracePageSizes && Verbose) {
2602 tty->print_cr("Reserving large pages individually."); 2602 tty->print_cr("Reserving large pages individually.");
2603 } 2603 }
2616 return NULL; 2616 return NULL;
2617 } 2617 }
2618 p_buf = (char *) VirtualAlloc(addr, 2618 p_buf = (char *) VirtualAlloc(addr,
2619 size_of_reserve, // size of Reserve 2619 size_of_reserve, // size of Reserve
2620 MEM_RESERVE, 2620 MEM_RESERVE,
2621 PAGE_EXECUTE_READWRITE); 2621 PAGE_READWRITE);
2622 // If reservation failed, return NULL 2622 // If reservation failed, return NULL
2623 if (p_buf == NULL) return NULL; 2623 if (p_buf == NULL) return NULL;
2624 2624
2625 release_memory(p_buf, bytes + _large_page_size); 2625 release_memory(p_buf, bytes + _large_page_size);
2626 // round up to page boundary. If the size_of_reserve did not 2626 // round up to page boundary. If the size_of_reserve did not
2657 p_new = NULL; 2657 p_new = NULL;
2658 } else { 2658 } else {
2659 p_new = (char *) VirtualAlloc(next_alloc_addr, 2659 p_new = (char *) VirtualAlloc(next_alloc_addr,
2660 bytes_to_rq, 2660 bytes_to_rq,
2661 MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, 2661 MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES,
2662 PAGE_EXECUTE_READWRITE); 2662 PAGE_READWRITE);
2663 if (p_new != NULL && exec) {
2664 DWORD oldprot;
2665 // Windows doc says to use VirtualProtect to get execute permissions
2666 VirtualProtect(next_alloc_addr, bytes_to_rq,
2667 PAGE_EXECUTE_READWRITE, &oldprot);
2668 }
2663 } 2669 }
2664 2670
2665 if (p_new == NULL) { 2671 if (p_new == NULL) {
2666 // Free any allocated pages 2672 // Free any allocated pages
2667 if (next_alloc_addr > p_buf) { 2673 if (next_alloc_addr > p_buf) {
2686 return p_buf; 2692 return p_buf;
2687 2693
2688 } else { 2694 } else {
2689 // normal policy just allocate it all at once 2695 // normal policy just allocate it all at once
2690 DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; 2696 DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
2691 char * res = (char *)VirtualAlloc(NULL, 2697 char * res = (char *)VirtualAlloc(NULL, bytes, flag, PAGE_READWRITE);
2692 bytes, 2698 if (res != NULL && exec) {
2693 flag, 2699 DWORD oldprot;
2694 PAGE_EXECUTE_READWRITE); 2700 // Windows doc says to use VirtualProtect to get execute permissions
2701 VirtualProtect(res, bytes, PAGE_EXECUTE_READWRITE, &oldprot);
2702 }
2695 return res; 2703 return res;
2696 } 2704 }
2697 } 2705 }
2698 2706
2699 bool os::release_memory_special(char* base, size_t bytes) { 2707 bool os::release_memory_special(char* base, size_t bytes) {
2701 } 2709 }
2702 2710
2703 void os::print_statistics() { 2711 void os::print_statistics() {
2704 } 2712 }
2705 2713
2706 bool os::commit_memory(char* addr, size_t bytes) { 2714 bool os::commit_memory(char* addr, size_t bytes, bool exec) {
2707 if (bytes == 0) { 2715 if (bytes == 0) {
2708 // Don't bother the OS with noops. 2716 // Don't bother the OS with noops.
2709 return true; 2717 return true;
2710 } 2718 }
2711 assert((size_t) addr % os::vm_page_size() == 0, "commit on page boundaries"); 2719 assert((size_t) addr % os::vm_page_size() == 0, "commit on page boundaries");
2712 assert(bytes % os::vm_page_size() == 0, "commit in page-sized chunks"); 2720 assert(bytes % os::vm_page_size() == 0, "commit in page-sized chunks");
2713 // Don't attempt to print anything if the OS call fails. We're 2721 // Don't attempt to print anything if the OS call fails. We're
2714 // probably low on resources, so the print itself may cause crashes. 2722 // probably low on resources, so the print itself may cause crashes.
2715 return VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_EXECUTE_READWRITE) != NULL; 2723 bool result = VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) != 0;
2716 } 2724 if (result != NULL && exec) {
2717 2725 DWORD oldprot;
2718 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint) { 2726 // Windows doc says to use VirtualProtect to get execute permissions
2719 return commit_memory(addr, size); 2727 return VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot) != 0;
2728 } else {
2729 return result;
2730 }
2731 }
2732
2733 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
2734 bool exec) {
2735 return commit_memory(addr, size, exec);
2720 } 2736 }
2721 2737
2722 bool os::uncommit_memory(char* addr, size_t bytes) { 2738 bool os::uncommit_memory(char* addr, size_t bytes) {
2723 if (bytes == 0) { 2739 if (bytes == 0) {
2724 // Don't bother the OS with noops. 2740 // Don't bother the OS with noops.
2748 2764
2749 DWORD old_status; 2765 DWORD old_status;
2750 2766
2751 // Strange enough, but on Win32 one can change protection only for committed 2767 // Strange enough, but on Win32 one can change protection only for committed
2752 // memory, not a big deal anyway, as bytes less or equal than 64K 2768 // memory, not a big deal anyway, as bytes less or equal than 64K
2753 if (!is_committed && !commit_memory(addr, bytes)) { 2769 if (!is_committed && !commit_memory(addr, bytes, prot == MEM_PROT_RWX)) {
2754 fatal("cannot commit protection page"); 2770 fatal("cannot commit protection page");
2755 } 2771 }
2756 // One cannot use os::guard_memory() here, as on Win32 guard page 2772 // One cannot use os::guard_memory() here, as on Win32 guard page
2757 // have different (one-shot) semantics, from MSDN on PAGE_GUARD: 2773 // have different (one-shot) semantics, from MSDN on PAGE_GUARD:
2758 // 2774 //
3246 if( Verbose && PrintMiscellaneous ) 3262 if( Verbose && PrintMiscellaneous )
3247 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); 3263 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
3248 #endif 3264 #endif
3249 3265
3250 if (!UseMembar) { 3266 if (!UseMembar) {
3251 address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_EXECUTE_READWRITE); 3267 address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READWRITE);
3252 guarantee( mem_serialize_page != NULL, "Reserve Failed for memory serialize page"); 3268 guarantee( mem_serialize_page != NULL, "Reserve Failed for memory serialize page");
3253 3269
3254 return_page = (address)VirtualAlloc(mem_serialize_page, os::vm_page_size(), MEM_COMMIT, PAGE_EXECUTE_READWRITE); 3270 return_page = (address)VirtualAlloc(mem_serialize_page, os::vm_page_size(), MEM_COMMIT, PAGE_READWRITE);
3255 guarantee( return_page != NULL, "Commit Failed for memory serialize page"); 3271 guarantee( return_page != NULL, "Commit Failed for memory serialize page");
3256 3272
3257 os::set_memory_serialize_page( mem_serialize_page ); 3273 os::set_memory_serialize_page( mem_serialize_page );
3258 3274
3259 #ifndef PRODUCT 3275 #ifndef PRODUCT