# NS4Plugins Module Memory Documentation

## Used OOM policies

The ns4plugins module traps all leaving methods called into other modules internally and no methods leave from the ns4plugins module. Return values are used to propagate OOM errors up from this module.

In OOM situations, the Netscape 4 plug-in API error value NPERR_OUT_OF_MEMORY_ERROR is returned to the plugin in several plug-in API methods. MemoryManager::RaiseCondition is used where there is no support for returning an OOM condition:

- The NPN_Status() method of the Netscape4 plug-in API.

## Who is handling OOM?

Apart from deleting memory to avoid leaks and to recover to a defined state, no actions are initiated from the ns4plugins module to free resources upon an OOM situation. Resources are freed as a result of:

- The OpNS4PluginHandler object is deleted when Opera is terminated.
- OpNS4Plugin objects are deleted from the layout module or when the OpNS4PluginHandler object is deleted.
- Internal ns4plugins objects like PluginMemoryHandler and PluginLibHandler are deleted when the OpNS4PluginHandler object is deleted.
- Internal PluginLib objects are deleted either when the OpNS4PluginHandler object is deleted or by an Opera timer funtionality (OpNS4PluginHandler::ReleaseUnusedResources()).

Also, URL objects, datadescriptors, PluginStream objects and other resources are released as a consequence of OpNS4Plugin objects being deleted.

## Description of flow

The layout module creates OpNS4Plugin objects by calling New() and starts the loading by calling AddStream() and NewStream() on the OpNS4Plugin object. The layout module resizes the plugin by calling SetWindow() on the OpNS4Plugin object. The rest of the OpNS4Plugin loading and running happens within the ns4plugins module. The OpNS4Plugin object is destroyed when it's deleted by the layout engine.

The plugin's library instance is not unloaded when the OpNSPlugin object is destroyed. The library instance is controlled by a timer functionality calling OpNS4PluginHandler::ReleaseUnusedResources(), which deletes inactive plugin library instances.

The plugin's memory handler is not created unless Opera activates a plugin using the memory methods of the Netscape 4 plug-in API. The memory handling is independent of the different plugin instances. A hash table is used in order to make the allocation and deallocation of memory fast and efficient. When Opera terminates, the memory handler is deleted.

## Heap memory usage

Third party code like plugins may use unlimited memory, which can be freed by deleting the documents containing the plugin activation.

Heap memory allocated in connection with an OpNSPlugin depends on the size of the footprint and memory usage for the OpNSPlugin. There is one OpNSPlugin object allocated per plug-in. The number and size of OBJECT/EMBED element attributes affect the heap memory used.

## Stack memory usage

Nothing exceptional.

## Static memory usage

Two global pointers PluginMemoryHandler and PluginHandler, an AProcInstance and a char array.

## Caching and freeing memory

Cache is used when the plugin initiates loading of urls.

## Freeing memory on exit

OpNS4PluginHandler::Destroy() frees the Plugin resources, deletes the PluginHandler and PluginLibHandler and activates PluginMemoryHandler::Destroy(). PluginMemoryHandler::Destroy() frees any memory not deallocated by plugins and deletes the PluginMemoryHandler.

## Temp buffers

For investigation.

## Memory tuning

For investigation.

## Tests

No tests exist.

## Coverage

Running the module release tests defined on wiki should cover a lot.

## Design choices

## Suggestions of improvements

For investigation.