Mercurial > hg > xemacs-beta
annotate src/ntheap.c @ 5127:a9c41067dd88 ben-lisp-object
more cleanups, terminology clarification, lots of doc work
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* internals/internals.texi (Introduction to Allocation):
* internals/internals.texi (Integers and Characters):
* internals/internals.texi (Allocation from Frob Blocks):
* internals/internals.texi (lrecords):
* internals/internals.texi (Low-level allocation):
Rewrite section on allocation of Lisp objects to reflect the new
reality. Remove references to nonexistent XSETINT and XSETCHAR.
modules/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c (allocate_pgconn):
* postgresql/postgresql.c (allocate_pgresult):
* postgresql/postgresql.h (struct Lisp_PGconn):
* postgresql/postgresql.h (struct Lisp_PGresult):
* ldap/eldap.c (allocate_ldap):
* ldap/eldap.h (struct Lisp_LDAP):
Same changes as in src/ dir. See large log there in ChangeLog,
but basically:
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
../hlo/src/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (old_alloc_sized_lcrecord):
* alloc.c (very_old_free_lcrecord):
* alloc.c (copy_lisp_object):
* alloc.c (zero_sized_lisp_object):
* alloc.c (zero_nonsized_lisp_object):
* alloc.c (lisp_object_storage_size):
* alloc.c (free_normal_lisp_object):
* alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC):
* alloc.c (ALLOC_FROB_BLOCK_LISP_OBJECT):
* alloc.c (Fcons):
* alloc.c (noseeum_cons):
* alloc.c (make_float):
* alloc.c (make_bignum):
* alloc.c (make_bignum_bg):
* alloc.c (make_ratio):
* alloc.c (make_ratio_bg):
* alloc.c (make_ratio_rt):
* alloc.c (make_bigfloat):
* alloc.c (make_bigfloat_bf):
* alloc.c (size_vector):
* alloc.c (make_compiled_function):
* alloc.c (Fmake_symbol):
* alloc.c (allocate_extent):
* alloc.c (allocate_event):
* alloc.c (make_key_data):
* alloc.c (make_button_data):
* alloc.c (make_motion_data):
* alloc.c (make_process_data):
* alloc.c (make_timeout_data):
* alloc.c (make_magic_data):
* alloc.c (make_magic_eval_data):
* alloc.c (make_eval_data):
* alloc.c (make_misc_user_data):
* alloc.c (Fmake_marker):
* alloc.c (noseeum_make_marker):
* alloc.c (size_string_direct_data):
* alloc.c (make_uninit_string):
* alloc.c (make_string_nocopy):
* alloc.c (mark_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (sweep_lcrecords_1):
* alloc.c (malloced_storage_size):
* buffer.c (allocate_buffer):
* buffer.c (compute_buffer_usage):
* buffer.c (DEFVAR_BUFFER_LOCAL_1):
* buffer.c (nuke_all_buffer_slots):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.h (struct buffer_text):
* buffer.h (struct buffer):
* bytecode.c:
* bytecode.c (make_compiled_function_args):
* bytecode.c (size_compiled_function_args):
* bytecode.h (struct compiled_function_args):
* casetab.c (allocate_case_table):
* casetab.h (struct Lisp_Case_Table):
* charset.h (struct Lisp_Charset):
* chartab.c (fill_char_table):
* chartab.c (Fmake_char_table):
* chartab.c (make_char_table_entry):
* chartab.c (copy_char_table_entry):
* chartab.c (Fcopy_char_table):
* chartab.c (put_char_table):
* chartab.h (struct Lisp_Char_Table_Entry):
* chartab.h (struct Lisp_Char_Table):
* console-gtk-impl.h (struct gtk_device):
* console-gtk-impl.h (struct gtk_frame):
* console-impl.h (struct console):
* console-msw-impl.h (struct Lisp_Devmode):
* console-msw-impl.h (struct mswindows_device):
* console-msw-impl.h (struct msprinter_device):
* console-msw-impl.h (struct mswindows_frame):
* console-msw-impl.h (struct mswindows_dialog_id):
* console-stream-impl.h (struct stream_console):
* console-stream.c (stream_init_console):
* console-tty-impl.h (struct tty_console):
* console-tty-impl.h (struct tty_device):
* console-tty.c (allocate_tty_console_struct):
* console-x-impl.h (struct x_device):
* console-x-impl.h (struct x_frame):
* console.c (allocate_console):
* console.c (nuke_all_console_slots):
* console.c (DEFVAR_CONSOLE_LOCAL_1):
* console.c (common_init_complex_vars_of_console):
* data.c (make_weak_list):
* data.c (make_weak_box):
* data.c (make_ephemeron):
* database.c:
* database.c (struct Lisp_Database):
* database.c (allocate_database):
* database.c (finalize_database):
* device-gtk.c (allocate_gtk_device_struct):
* device-impl.h (struct device):
* device-msw.c:
* device-msw.c (mswindows_init_device):
* device-msw.c (msprinter_init_device):
* device-msw.c (finalize_devmode):
* device-msw.c (allocate_devmode):
* device-tty.c (allocate_tty_device_struct):
* device-x.c (allocate_x_device_struct):
* device.c:
* device.c (nuke_all_device_slots):
* device.c (allocate_device):
* dialog-msw.c (handle_question_dialog_box):
* elhash.c:
* elhash.c (struct Lisp_Hash_Table):
* elhash.c (finalize_hash_table):
* elhash.c (make_general_lisp_hash_table):
* elhash.c (Fcopy_hash_table):
* elhash.h (htentry):
* emacs.c (main_1):
* eval.c:
* eval.c (size_multiple_value):
* event-stream.c (finalize_command_builder):
* event-stream.c (allocate_command_builder):
* event-stream.c (free_command_builder):
* event-stream.c (event_stream_generate_wakeup):
* event-stream.c (event_stream_resignal_wakeup):
* event-stream.c (event_stream_disable_wakeup):
* event-stream.c (event_stream_wakeup_pending_p):
* events.h (struct Lisp_Timeout):
* events.h (struct command_builder):
* extents-impl.h:
* extents-impl.h (struct extent_auxiliary):
* extents-impl.h (struct extent_info):
* extents-impl.h (set_extent_no_chase_aux_field):
* extents-impl.h (set_extent_no_chase_normal_field):
* extents.c:
* extents.c (gap_array_marker):
* extents.c (gap_array):
* extents.c (extent_list_marker):
* extents.c (extent_list):
* extents.c (stack_of_extents):
* extents.c (gap_array_make_marker):
* extents.c (extent_list_make_marker):
* extents.c (allocate_extent_list):
* extents.c (SLOT):
* extents.c (mark_extent_auxiliary):
* extents.c (allocate_extent_auxiliary):
* extents.c (attach_extent_auxiliary):
* extents.c (size_gap_array):
* extents.c (finalize_extent_info):
* extents.c (allocate_extent_info):
* extents.c (uninit_buffer_extents):
* extents.c (allocate_soe):
* extents.c (copy_extent):
* extents.c (vars_of_extents):
* extents.h:
* faces.c (allocate_face):
* faces.h (struct Lisp_Face):
* faces.h (struct face_cachel):
* file-coding.c:
* file-coding.c (finalize_coding_system):
* file-coding.c (sizeof_coding_system):
* file-coding.c (Fcopy_coding_system):
* file-coding.h (struct Lisp_Coding_System):
* file-coding.h (MARKED_SLOT):
* fns.c (size_bit_vector):
* font-mgr.c:
* font-mgr.c (finalize_fc_pattern):
* font-mgr.c (print_fc_pattern):
* font-mgr.c (Ffc_pattern_p):
* font-mgr.c (Ffc_pattern_create):
* font-mgr.c (Ffc_name_parse):
* font-mgr.c (Ffc_name_unparse):
* font-mgr.c (Ffc_pattern_duplicate):
* font-mgr.c (Ffc_pattern_add):
* font-mgr.c (Ffc_pattern_del):
* font-mgr.c (Ffc_pattern_get):
* font-mgr.c (fc_config_create_using):
* font-mgr.c (fc_strlist_to_lisp_using):
* font-mgr.c (fontset_to_list):
* font-mgr.c (Ffc_config_p):
* font-mgr.c (Ffc_config_up_to_date):
* font-mgr.c (Ffc_config_build_fonts):
* font-mgr.c (Ffc_config_get_cache):
* font-mgr.c (Ffc_config_get_fonts):
* font-mgr.c (Ffc_config_set_current):
* font-mgr.c (Ffc_config_get_blanks):
* font-mgr.c (Ffc_config_get_rescan_interval):
* font-mgr.c (Ffc_config_set_rescan_interval):
* font-mgr.c (Ffc_config_app_font_add_file):
* font-mgr.c (Ffc_config_app_font_add_dir):
* font-mgr.c (Ffc_config_app_font_clear):
* font-mgr.c (size):
* font-mgr.c (Ffc_config_substitute):
* font-mgr.c (Ffc_font_render_prepare):
* font-mgr.c (Ffc_font_match):
* font-mgr.c (Ffc_font_sort):
* font-mgr.c (finalize_fc_config):
* font-mgr.c (print_fc_config):
* font-mgr.h:
* font-mgr.h (struct fc_pattern):
* font-mgr.h (XFC_PATTERN):
* font-mgr.h (struct fc_config):
* font-mgr.h (XFC_CONFIG):
* frame-gtk.c (allocate_gtk_frame_struct):
* frame-impl.h (struct frame):
* frame-msw.c (mswindows_init_frame_1):
* frame-x.c (allocate_x_frame_struct):
* frame.c (nuke_all_frame_slots):
* frame.c (allocate_frame_core):
* gc.c:
* gc.c (GC_CHECK_NOT_FREE):
* glyphs.c (finalize_image_instance):
* glyphs.c (allocate_image_instance):
* glyphs.c (Fcolorize_image_instance):
* glyphs.c (allocate_glyph):
* glyphs.c (unmap_subwindow_instance_cache_mapper):
* glyphs.c (register_ignored_expose):
* glyphs.h (struct Lisp_Image_Instance):
* glyphs.h (struct Lisp_Glyph):
* glyphs.h (struct glyph_cachel):
* glyphs.h (struct expose_ignore):
* gui.c (allocate_gui_item):
* gui.h (struct Lisp_Gui_Item):
* keymap.c (struct Lisp_Keymap):
* keymap.c (make_keymap):
* lisp.h:
* lisp.h (struct Lisp_String_Direct_Data):
* lisp.h (struct Lisp_String_Indirect_Data):
* lisp.h (struct Lisp_Vector):
* lisp.h (struct Lisp_Bit_Vector):
* lisp.h (DECLARE_INLINE_LISP_BIT_VECTOR):
* lisp.h (struct weak_box):
* lisp.h (struct ephemeron):
* lisp.h (struct weak_list):
* lrecord.h:
* lrecord.h (struct lrecord_implementation):
* lrecord.h (MC_ALLOC_CALL_FINALIZER):
* lrecord.h (struct lcrecord_list):
* lstream.c (finalize_lstream):
* lstream.c (sizeof_lstream):
* lstream.c (Lstream_new):
* lstream.c (Lstream_delete):
* lstream.h (struct lstream):
* marker.c:
* marker.c (finalize_marker):
* marker.c (compute_buffer_marker_usage):
* mule-charset.c:
* mule-charset.c (make_charset):
* mule-charset.c (compute_charset_usage):
* objects-impl.h (struct Lisp_Color_Instance):
* objects-impl.h (struct Lisp_Font_Instance):
* objects-tty-impl.h (struct tty_color_instance_data):
* objects-tty-impl.h (struct tty_font_instance_data):
* objects-tty.c (tty_initialize_color_instance):
* objects-tty.c (tty_initialize_font_instance):
* objects.c (finalize_color_instance):
* objects.c (Fmake_color_instance):
* objects.c (finalize_font_instance):
* objects.c (Fmake_font_instance):
* objects.c (reinit_vars_of_objects):
* opaque.c:
* opaque.c (sizeof_opaque):
* opaque.c (make_opaque_ptr):
* opaque.c (free_opaque_ptr):
* opaque.h:
* opaque.h (Lisp_Opaque):
* opaque.h (Lisp_Opaque_Ptr):
* print.c (printing_unreadable_lcrecord):
* print.c (external_object_printer):
* print.c (debug_p4):
* process.c (finalize_process):
* process.c (make_process_internal):
* procimpl.h (struct Lisp_Process):
* rangetab.c (Fmake_range_table):
* rangetab.c (Fcopy_range_table):
* rangetab.h (struct Lisp_Range_Table):
* scrollbar.c:
* scrollbar.c (create_scrollbar_instance):
* scrollbar.c (compute_scrollbar_instance_usage):
* scrollbar.h (struct scrollbar_instance):
* specifier.c (finalize_specifier):
* specifier.c (sizeof_specifier):
* specifier.c (set_specifier_caching):
* specifier.h (struct Lisp_Specifier):
* specifier.h (struct specifier_caching):
* symeval.h:
* symeval.h (SYMBOL_VALUE_MAGIC_P):
* symeval.h (DEFVAR_SYMVAL_FWD):
* symsinit.h:
* syntax.c (init_buffer_syntax_cache):
* syntax.h (struct syntax_cache):
* toolbar.c:
* toolbar.c (allocate_toolbar_button):
* toolbar.c (update_toolbar_button):
* toolbar.h (struct toolbar_button):
* tooltalk.c (struct Lisp_Tooltalk_Message):
* tooltalk.c (make_tooltalk_message):
* tooltalk.c (struct Lisp_Tooltalk_Pattern):
* tooltalk.c (make_tooltalk_pattern):
* ui-gtk.c:
* ui-gtk.c (allocate_ffi_data):
* ui-gtk.c (emacs_gtk_object_finalizer):
* ui-gtk.c (allocate_emacs_gtk_object_data):
* ui-gtk.c (allocate_emacs_gtk_boxed_data):
* ui-gtk.h:
* window-impl.h (struct window):
* window-impl.h (struct window_mirror):
* window.c (finalize_window):
* window.c (allocate_window):
* window.c (new_window_mirror):
* window.c (mark_window_as_deleted):
* window.c (make_dummy_parent):
* window.c (compute_window_mirror_usage):
* window.c (compute_window_usage):
Overall point of this change and previous ones in this repository:
(1) Introduce new, clearer terminology: everything other than int
or char is a "record" object, which comes in two types: "normal
objects" and "frob-block objects". Fix up all places that
referred to frob-block objects as "simple", "basic", etc.
(2) Provide an advertised interface for doing operations on Lisp
objects, including creating new types, that is clean and
consistent in its naming, uses the above-referenced terms and
avoids referencing "lrecords", "old lcrecords", etc., which should
hide under the surface.
(3) Make the size_in_bytes and finalizer methods take a
Lisp_Object rather than a void * for consistency with other methods.
(4) Separate finalizer method into finalizer and disksaver, so
that normal finalize methods don't have to worry about disksaving.
Other specifics:
(1) Renaming:
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
implementation->basic_p -> implementation->frob_block_p
ALLOCATE_FIXED_TYPE_AND_SET_IMPL -> ALLOC_FROB_BLOCK_LISP_OBJECT
*FCCONFIG*, wrap_fcconfig -> *FC_CONFIG*, wrap_fc_config
*FCPATTERN*, wrap_fcpattern -> *FC_PATTERN*, wrap_fc_pattern
(the last two changes make the naming of these macros consistent
with the naming of all other macros, since the objects are named
fc-config and fc-pattern with a hyphen)
(2) Lots of documentation fixes in lrecord.h.
(3) Eliminate macros for copying, freeing, zeroing objects, getting
their storage size. Instead, new functions:
zero_sized_lisp_object()
zero_nonsized_lisp_object()
lisp_object_storage_size()
free_normal_lisp_object()
(copy_lisp_object() already exists)
LISP_OBJECT_FROB_BLOCK_P() (actually a macro)
Eliminated:
free_lrecord()
zero_lrecord()
copy_lrecord()
copy_sized_lrecord()
old_copy_lcrecord()
old_copy_sized_lcrecord()
old_zero_lcrecord()
old_zero_sized_lcrecord()
LISP_OBJECT_STORAGE_SIZE()
COPY_SIZED_LISP_OBJECT()
COPY_SIZED_LCRECORD()
COPY_LISP_OBJECT()
ZERO_LISP_OBJECT()
FREE_LISP_OBJECT()
(4) Catch the remaining places where lrecord stuff was used directly
and use the advertised interface, e.g. alloc_sized_lrecord() ->
ALLOC_SIZED_LISP_OBJECT().
(5) Make certain statically-declared pseudo-objects
(buffer_local_flags, console_local_flags) have their lheader
initialized correctly, so things like copy_lisp_object() can work
on them. Make extent_auxiliary_defaults a proper heap object
Vextent_auxiliary_defaults, and make extent auxiliaries dumpable
so that this object can be dumped. allocate_extent_auxiliary()
now just creates the object, and attach_extent_auxiliary()
creates an extent auxiliary and attaches to an extent, like the
old allocate_extent_auxiliary().
(6) Create EXTENT_AUXILIARY_SLOTS macro, similar to the foo-slots.h
files but in a macro instead of a file. The purpose is to avoid
duplication when iterating over all the slots in an extent auxiliary.
Use it.
(7) In lstream.c, don't zero out object after allocation because
allocation routines take care of this.
(8) In marker.c, fix a mistake in computing marker overhead.
(9) In print.c, clean up printing_unreadable_lcrecord(),
external_object_printer() to avoid lots of ifdef NEW_GC's.
(10) Separate toolbar-button allocation into a separate
allocate_toolbar_button() function for use in the example code
in lrecord.h.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Fri, 05 Mar 2010 04:08:17 -0600 |
parents | ecf1ebac70d8 |
children | 3889ef128488 308d34e9f07d |
rev | line source |
---|---|
428 | 1 /* Heap management routines for XEmacs on Windows NT. |
2 Copyright (C) 1994 Free Software Foundation, Inc. | |
3 | |
4 This file is part of XEmacs. | |
5 | |
6 XEmacs is free software; you can redistribute it and/or modify it | |
7 under the terms of the GNU General Public License as published by the | |
8 Free Software Foundation; either version 2, or (at your option) any | |
9 later version. | |
10 | |
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with XEmacs; see the file COPYING. If not, write to the Free | |
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
19 02111-1307, USA. | |
20 | |
21 Geoff Voelker (voelker@cs.washington.edu) 7-29-94 */ | |
22 | |
23 /* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */ | |
771 | 24 /* Synced with FSF Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> |
25 (Note: Sync messages from Marc Paquette may indicate | |
26 incomplete synching, so beware.) | |
27 */ | |
428 | 28 |
814 | 29 /* This file has been Mule-ized, Ben Wing, 4-13-02. */ |
30 | |
428 | 31 #include <config.h> |
771 | 32 #include "lisp.h" |
428 | 33 |
814 | 34 #include "sysdep.h" |
771 | 35 #include "syswindows.h" |
428 | 36 |
37 /* This gives us the page size and the size of the allocation unit on NT. */ | |
38 SYSTEM_INFO sysinfo_cache; | |
39 unsigned long syspage_mask = 0; | |
40 | |
41 /* These are defined to get Emacs to compile, but are not used. */ | |
42 int edata; | |
43 int etext; | |
44 | |
45 /* Cache information describing the NT system for later use. */ | |
46 void | |
47 cache_system_info (void) | |
48 { | |
49 /* Cache page size, allocation unit, processor type, etc. */ | |
50 GetSystemInfo (&sysinfo_cache); | |
51 syspage_mask = sysinfo_cache.dwPageSize - 1; | |
52 } | |
53 | |
54 /* Round ADDRESS up to be aligned with ALIGN. */ | |
2367 | 55 URawbyte * |
56 round_to_next (URawbyte *address, unsigned long align) | |
428 | 57 { |
58 unsigned long tmp; | |
59 | |
60 tmp = (unsigned long) address; | |
61 tmp = (tmp + align - 1) / align; | |
62 | |
2367 | 63 return (URawbyte *) (tmp * align); |
428 | 64 } |
65 | |
66 /* Info for keeping track of our heap. */ | |
2367 | 67 URawbyte *data_region_base = UNINIT_PTR; |
68 URawbyte *data_region_end = UNINIT_PTR; | |
69 URawbyte *real_data_region_end = UNINIT_PTR; | |
428 | 70 unsigned long data_region_size = UNINIT_LONG; |
71 unsigned long reserved_heap_size = UNINIT_LONG; | |
72 | |
73 /* The start of the data segment. */ | |
2367 | 74 URawbyte * |
428 | 75 get_data_start (void) |
76 { | |
77 return data_region_base; | |
78 } | |
79 | |
80 /* The end of the data segment. */ | |
2367 | 81 URawbyte * |
428 | 82 get_data_end (void) |
83 { | |
84 return data_region_end; | |
85 } | |
86 | |
2367 | 87 static URawbyte * |
428 | 88 allocate_heap (void) |
89 { | |
90 /* The base address for our GNU malloc heap is chosen in conjunction | |
91 with the link settings for temacs.exe which control the stack size, | |
92 the initial default process heap size and the executable image base | |
93 address. The link settings and the malloc heap base below must all | |
94 correspond; the relationship between these values depends on how NT | |
95 and Win95 arrange the virtual address space for a process (and on | |
96 the size of the code and data segments in temacs.exe). | |
97 | |
98 The most important thing is to make base address for the executable | |
99 image high enough to leave enough room between it and the 4MB floor | |
100 of the process address space on Win95 for the primary thread stack, | |
101 the process default heap, and other assorted odds and ends | |
102 (eg. environment strings, private system dll memory etc) that are | |
103 allocated before temacs has a chance to grab its malloc arena. The | |
104 malloc heap base can then be set several MB higher than the | |
105 executable image base, leaving enough room for the code and data | |
106 segments. | |
107 | |
108 Because some parts of Emacs can use rather a lot of stack space | |
109 (for instance, the regular expression routines can potentially | |
110 allocate several MB of stack space) we allow 8MB for the stack. | |
111 | |
112 Allowing 1MB for the default process heap, and 1MB for odds and | |
113 ends, we can base the executable at 16MB and still have a generous | |
114 safety margin. At the moment, the executable has about 810KB of | |
115 code (for x86) and about 550KB of data - on RISC platforms the code | |
116 size could be roughly double, so if we allow 4MB for the executable | |
117 we will have plenty of room for expansion. | |
118 | |
119 Thus we would like to set the malloc heap base to 20MB. However, | |
120 Win95 refuses to allocate the heap starting at this address, so we | |
121 set the base to 27MB to make it happy. Since Emacs now leaves | |
122 28 bits available for pointers, this lets us use the remainder of | |
123 the region below the 256MB line for our malloc arena - 229MB is | |
124 still a pretty decent arena to play in! */ | |
125 | |
126 unsigned long base = 0x01B00000; /* 27MB */ | |
438 | 127 /* Temporary hack for the non-starting problem - use 28 (256Mb) rather than VALBITS (1Gb) */ |
128 unsigned long end = 1 << 28; /* 256MB */ | |
428 | 129 void *ptr = NULL; |
130 | |
131 #define NTHEAP_PROBE_BASE 1 | |
132 #if NTHEAP_PROBE_BASE /* This is never normally defined */ | |
133 /* Try various addresses looking for one the kernel will let us have. */ | |
134 while (!ptr && (base < end)) | |
135 { | |
136 reserved_heap_size = end - base; | |
137 ptr = VirtualAlloc ((void *) base, | |
138 get_reserved_heap_size (), | |
139 MEM_RESERVE, | |
140 PAGE_NOACCESS); | |
141 base += 0x00100000; /* 1MB increment */ | |
142 } | |
143 #else | |
144 reserved_heap_size = end - base; | |
145 ptr = VirtualAlloc ((void *) base, | |
146 get_reserved_heap_size (), | |
147 MEM_RESERVE, | |
148 PAGE_NOACCESS); | |
149 #endif | |
150 | |
2367 | 151 return (URawbyte *) ptr; |
428 | 152 } |
153 | |
154 | |
155 /* Emulate Unix sbrk. */ | |
156 void * | |
157 sbrk (unsigned long increment) | |
158 { | |
159 void *result; | |
160 long size = (long) increment; | |
161 | |
162 /* Allocate our heap if we haven't done so already. */ | |
163 if (data_region_base == UNINIT_PTR) | |
164 { | |
165 data_region_base = allocate_heap (); | |
166 if (!data_region_base) | |
167 return NULL; | |
168 | |
169 data_region_end = data_region_base; | |
170 real_data_region_end = data_region_end; | |
171 data_region_size = get_reserved_heap_size (); | |
172 } | |
173 | |
174 result = data_region_end; | |
175 | |
176 /* If size is negative, shrink the heap by decommitting pages. */ | |
177 if (size < 0) | |
178 { | |
179 int new_size; | |
2367 | 180 URawbyte *new_data_region_end; |
428 | 181 |
182 size = -size; | |
183 | |
184 /* Sanity checks. */ | |
185 if ((data_region_end - size) < data_region_base) | |
186 return NULL; | |
187 | |
188 /* We can only decommit full pages, so allow for | |
189 partial deallocation [cga]. */ | |
190 new_data_region_end = (data_region_end - size); | |
2367 | 191 new_data_region_end = (URawbyte *) |
428 | 192 ((long) (new_data_region_end + syspage_mask) & ~syspage_mask); |
193 new_size = real_data_region_end - new_data_region_end; | |
194 real_data_region_end = new_data_region_end; | |
195 if (new_size > 0) | |
196 { | |
197 /* Decommit size bytes from the end of the heap. */ | |
198 if (!VirtualFree (real_data_region_end, new_size, MEM_DECOMMIT)) | |
199 return NULL; | |
200 } | |
201 | |
202 data_region_end -= size; | |
203 } | |
204 /* If size is positive, grow the heap by committing reserved pages. */ | |
205 else if (size > 0) | |
206 { | |
207 /* Sanity checks. */ | |
208 if ((data_region_end + size) > | |
209 (data_region_base + get_reserved_heap_size ())) | |
210 return NULL; | |
211 | |
212 /* Commit more of our heap. */ | |
213 if (VirtualAlloc (data_region_end, size, MEM_COMMIT, | |
214 PAGE_READWRITE) == NULL) | |
215 return NULL; | |
216 data_region_end += size; | |
217 | |
218 /* We really only commit full pages, so record where | |
219 the real end of committed memory is [cga]. */ | |
2367 | 220 real_data_region_end = (URawbyte *) |
428 | 221 ((long) (data_region_end + syspage_mask) & ~syspage_mask); |
222 } | |
223 | |
224 return result; | |
225 } | |
226 | |
1330 | 227 #if !defined (HEAP_IN_DATA) && !defined (PDUMP) |
428 | 228 |
229 /* Recreate the heap from the data that was dumped to the executable. | |
230 EXECUTABLE_PATH tells us where to find the executable. */ | |
231 void | |
814 | 232 recreate_heap (Extbyte *executable_path) |
428 | 233 { |
442 | 234 /* First reserve the upper part of our heap. (We reserve first |
235 because there have been problems in the past where doing the | |
236 mapping first has loaded DLLs into the VA space of our heap.) */ | |
428 | 237 |
442 | 238 /* Query the region at the end of the committed heap */ |
239 void *tmp; | |
240 MEMORY_BASIC_INFORMATION info; | |
241 DWORD size; | |
2367 | 242 URawbyte *base = get_heap_end (); |
243 URawbyte *end = | |
814 | 244 base + get_reserved_heap_size () - get_committed_heap_size (); |
647 | 245 VirtualQuery (base, &info, sizeof (info)); |
442 | 246 if (info.State != MEM_FREE) |
814 | 247 { |
248 /* Oops, something has already reserved or commited it, nothing | |
249 we can do but exit */ | |
250 Extbyte buf[256]; | |
251 sprintf (buf, | |
252 "XEmacs cannot start because the memory region required " | |
253 "by the heap is not available.\n" | |
254 "(BaseAddress = 0x%lx, AllocationBase = 0x%lx, " | |
255 "Size = 0x%lx, State = %s, Type = %s)", | |
256 info.BaseAddress, info.AllocationBase, info.RegionSize, | |
257 info.State == MEM_COMMIT ? "COMMITED" : "RESERVED", | |
258 info.Type == MEM_IMAGE ? "IMAGE" : | |
259 info.Type == MEM_MAPPED ? "MAPPED" : "PRIVATE"); | |
260 MessageBoxA (NULL, buf, "XEmacs", MB_OK | MB_ICONSTOP); | |
261 exit(1); | |
262 } | |
442 | 263 |
264 /* Now try and reserve as much as possible */ | |
647 | 265 size = min (info.RegionSize, (DWORD) (end - base)); |
442 | 266 tmp = VirtualAlloc (base, size, MEM_RESERVE, PAGE_NOACCESS); |
428 | 267 if (!tmp) |
814 | 268 { |
269 /* Can't reserve it, nothing we can do but exit */ | |
270 Extbyte buf[256]; | |
271 sprintf (buf, | |
272 "XEmacs cannot start because it couldn't reserve space " | |
273 "required for the heap.\n" | |
274 "(VirtualAlloc at 0x%lx of 0x%lx failed (%d))", | |
275 base, size, GetLastError()); | |
276 MessageBoxA (NULL, buf, "XEmacs", MB_OK | MB_ICONSTOP); | |
277 exit (1); | |
278 } | |
428 | 279 |
280 /* We read in the data for the .bss section from the executable | |
281 first and map in the heap from the executable second to prevent | |
282 any funny interactions between file I/O and file mapping. */ | |
283 read_in_bss (executable_path); | |
284 map_in_heap (executable_path); | |
285 | |
286 /* Update system version information to match current system. */ | |
287 cache_system_info (); | |
288 } | |
1330 | 289 |
290 #endif /* !defined (HEAP_IN_DATA) && !defined (PDUMP) */ | |
428 | 291 |
292 /* Round the heap up to the given alignment. */ | |
293 void | |
294 round_heap (unsigned long align) | |
295 { | |
296 unsigned long needs_to_be; | |
297 unsigned long need_to_alloc; | |
298 | |
299 needs_to_be = (unsigned long) round_to_next (get_heap_end (), align); | |
300 need_to_alloc = needs_to_be - (unsigned long) get_heap_end (); | |
301 | |
302 if (need_to_alloc) | |
303 sbrk (need_to_alloc); | |
304 } | |
305 | |
707 | 306 #if ((_MSC_VER >= 1000) && (_MSC_VER < 1300)) |
428 | 307 |
308 /* MSVC 4.2 invokes these functions from mainCRTStartup to initialize | |
309 a heap via HeapCreate. They are normally defined by the runtime, | |
310 but we override them here so that the unnecessary HeapCreate call | |
311 is not performed. */ | |
312 | |
707 | 313 /* MSVC 7.0 does not allow you to redefine _heap_init or _heap_term. */ |
314 | |
428 | 315 int __cdecl |
316 _heap_init (void) | |
317 { | |
318 /* Stepping through the assembly indicates that mainCRTStartup is | |
319 expecting a nonzero success return value. */ | |
320 return 1; | |
321 } | |
322 | |
323 void __cdecl | |
324 _heap_term (void) | |
325 { | |
326 return; | |
327 } | |
328 | |
329 #endif |