def isMarshalConstant(constant_value): """ Decide if we want to use marshal to create a constant. The reason we do this, is because creating dictionaries with 700 elements creates a lot of C code, while gaining usually no performance at all. The MSVC compiler is especially notorious about hanging like forever with this active, due to its optimizer not scaling. Therefore we use a constant "weight" (how expensive it is), and apply that to decide. If marshal is not possible, or constant "weight" is too large, we don't do it. Also, for some constants, marshal can fail, and return other values. Check that too. In that case, we have to create it. """ if not decideMarshal(constant_value): return False if getConstantWeight(constant_value) < 20: return False marshal_value = marshal.dumps(constant_value) restored = marshal.loads(marshal_value) r = compareConstants(constant_value, restored) if not r: pass # TODO: Potentially warn about these, where that is not the case. return r
def attemptToMarshal(constant_identifier, constant_value, emit): """ Try and marshal a value, if so decided. Indicate with return value. See above for why marshal is only used in problematic cases. """ if not isMarshalConstant(constant_value): return False marshal_value = marshal.dumps(constant_value) restored = marshal.loads(marshal_value) # TODO: The check in isMarshalConstant is currently preventing this from # happening. if not compareConstants(constant_value, restored): warning("Problem with marshal of constant %r", constant_value) return False emit( "%s = PyMarshal_ReadObjectFromString( (char *)%s );" % (constant_identifier, stream_data.getStreamDataCode(marshal_value)) ) return True
def getMarshalCode(constant_identifier, constant_value, emit): """ Force the marshal of a value. """ marshal_value = marshal.dumps(constant_value) restored = marshal.loads(marshal_value) assert compareConstants(constant_value, restored) emit("%s = PyMarshal_ReadObjectFromString( (char *)%s );" % (constant_identifier, stream_data.getStreamDataCode(marshal_value)))
def getMarshalCode(constant_identifier, constant_value, emit): """ Force the marshal of a value. """ marshal_value = marshal.dumps(constant_value) restored = marshal.loads(marshal_value) assert compareConstants(constant_value, restored) emit( "%s = PyMarshal_ReadObjectFromString( (char *)%s );" % (constant_identifier, stream_data.getStreamDataCode(marshal_value)) )
def isMarshalConstant(constant_value): """ Decide if we want to use marshal to create a constant. The reason we do this, is because creating dictionaries with 700 elements creates a lot of C code, while gaining usually no performance at all. The MSVC compiler is especially notorious about hanging like forever with this active, due to its optimizer not scaling. Therefore we use a constant "weight" (how expensive it is), and apply that to decide. If marshal is not possible, or constant "weight" is too large, we don't do it. Also, for some constants, marshal can fail, and return other values. Check that too. In that case, we have to create it. """ if not decideMarshal(constant_value): return False if getConstantWeight(constant_value) < 20: return False try: marshal_value = marshal.dumps(constant_value) except ValueError: if Options.isDebug(): warning("Failed to marshal constant %r." % constant_value) return False restored = marshal.loads(marshal_value) r = compareConstants(constant_value, restored) if not r: pass # TODO: Potentially warn about these, where that is not the case. return r