summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2013-08-24 10:36:20 +0100
committerKen Sharp <ken.sharp@artifex.com>2013-08-24 10:36:20 +0100
commit2001f469b539a5ccce301ace5d6384b6b7e46888 (patch)
tree556b32150caf8dd973e3ecad98fa3207b27a0b16
parentc1510d726063080559e9597db7d4a686f2ca4eae (diff)
downloadghostpdl-2001f469b539a5ccce301ace5d6384b6b7e46888.tar.gz
Fix -dUseCIEColor (part of the whole VM allocation problem)
See commit ae930279498a5961fcf5d70ffe86864883609cbc for a lengthy explanation) of the background to this problem. The fix for the original problem involved always creating the device dictionary for setpagdevice in local VM. Following on from that we discover the following in zdsp1.c gstate_check_space(i_ctx_t *i_ctx_p, int_gstate *isp, uint space) { /* * ****** WORKAROUND ALERT ****** * This code doesn't check the space of the non-refs, or copy their * contents, so it can create dangling references from global VM to * local VM. Because of this, we simply disallow writing into gstates * in global VM (including creating them in the first place) if the * save level is greater than 0. * ****** WORKAROUND ALERT ****** Now, if we execute the Display PostScript .savelocalstate routine, its vital that the gstate and all its contents be in global VM in order to satisfy the test in zdps1.c. So, any calls to setpagedevice before the call to .savelocal must allocate the page device dictionary in global VM (as a pointer to the device dictionary is saved in the gstate) Thus we need a way to tell setpagedevice to allocate its dictionary in global VM, even though we usually want it in local VM. This commit adds a somewhat hacky method for this, we insert a specific key /..StartupGlobal in the page device dictionary. If setpagedevice finds this key in the dictionary we allocate the dict in global VM, and remove the key. We then use this key in a couple of places in gs_init.ps where we execute setpagedevice *before* we've reached .savelocalstate. This fixes all the myriad problems with allocation states and gives us a way to add any more that are required. I've put a comment into gs_init.ps immediately before /.savelocalstate so at least in the future it will be easier to figure out where this is required. I've searched all the initialisation files looking to see if there are any other likely places (the INITFILES string is parsed before we get to .savelocalstate) and they all look acceptable. None of the routines actually execute setpagedevice. No cluster differences expected as none of this is tested
-rw-r--r--gs/Resource/Init/gs_init.ps13
-rw-r--r--gs/Resource/Init/gs_setpd.ps9
2 files changed, 15 insertions, 7 deletions
diff --git a/gs/Resource/Init/gs_init.ps b/gs/Resource/Init/gs_init.ps
index 351dc9ae3..69ff9f0ae 100644
--- a/gs/Resource/Init/gs_init.ps
+++ b/gs/Resource/Init/gs_init.ps
@@ -1909,7 +1909,7 @@ put % Policies in pagedevice
% so that .getuseciecolor has the correct value (see gs_setpd.ps)
/setpagedevice where {
pop systemdict /UseCIEColor known {
- mark /UseCIEColor UseCIEColor .dicttomark setpagedevice
+ mark /UseCIEColor UseCIEColor /..StartupGlobal //true .dicttomark setpagedevice
} if
} if
@@ -2040,7 +2040,9 @@ readonly def
% properties and pagedevice .LockSafetyParams in agreement even
% after a restore that changes the value to false.
currentglobal currentpagedevice gcheck setglobal % use correct VM space
- << /.LockSafetyParamsGlobal //true >> setpagedevice
+ << /.LockSafetyParams //true
+ /..StartupGlobal //true
+ >> setpagedevice
setglobal
//SAFETY /safe //true .forceput % overrides readonly
} .bind executeonly odef
@@ -2176,6 +2178,13 @@ $error /.nosetlocal //false put
(END GLOBAL) VMDEBUG
+%% .savelocalstate is part of Display PostScript (if included). Part of the function of
+%% the .savelocalstate routine is to store the 'initial saved gstate' (savedinitialgstate)
+%% in systemdict. The code in dps1.c, gstate_check_space, disallows writing or creating
+%% gstates in global VM in certain conditions. If we execute setpagedevice before we
+%% reach this point, we must ensure that we do so using /..StartupGlobal so that
+%% the dictionary is defined in global VM, because the gstate contains a pointer to the
+%% device dictionary, and if that is allocated in local VM we will fail the gstate check.
/.savelocalstate where {
% If we might create new contexts, save away copies of all dictionaries
% referenced from systemdict that are stored in local VM,
diff --git a/gs/Resource/Init/gs_setpd.ps b/gs/Resource/Init/gs_setpd.ps
index 70513bce7..41c0c4242 100644
--- a/gs/Resource/Init/gs_setpd.ps
+++ b/gs/Resource/Init/gs_setpd.ps
@@ -675,11 +675,10 @@ SETPDDEBUG { (Result of putting.) = pstack flush } if
% solution is to make sure the VM mode is global during
% startup (to satisfy gs_dps.ps) and local thereafter
% (to satisfy the WordPerfect bug).
- dup dup length 1 eq exch /.LockSafetyParamsGlobal known and {
- currentglobal exch true setglobal
- dup /.LockSafetyParamsGlobal get
- 1 index /.LockSafetyParamsGlobal undef
- 1 index /.LockSafetyParams 3 -1 roll put
+ dup /..StartupGlobal known
+ {
+ currentglobal exch true setglobal
+ dup /..StartupGlobal undef
} {
% ensure that we are always in local VM mode to avoid
% mismatches. This is because we always create child