| 3032 | // TODO(simon): We cannot yet reliably detect which modules are used within workers, |
| 3033 | // so we just perform a GC instead |
| 3034 | performGcNow(entry.jsContext); |
| 3035 | } else { |
| 3036 | // Unload modules as much as we can, then kick off a GC. |
| 3037 | // Re-do this process until we can't unload a module anymore. |
| 3038 | auto unloaded = true; |
| 3039 | while (unloaded) { |
| 3040 | unloaded = false; |
| 3041 | while (unloadNextUnusedModule(entry)) { |
| 3042 | unloaded = true; |
| 3043 | } |
| 3044 | |
| 3045 | performGcNow(entry.jsContext); |
| 3046 | } |
| 3047 | } |
| 3048 | |
| 3049 | completionGroup->leave(); |
| 3050 | }); |
| 3051 | } |
| 3052 | |
| 3053 | void JavaScriptRuntime::unloadUnusedModules(DispatchFunction completion) { |
| 3054 | auto group = makeShared<AsyncGroup>(); |
| 3055 | |
| 3056 | unloadUnusedModules(group); |
| 3057 | |
| 3058 | group->notify(std::move(completion)); |
| 3059 | } |
| 3060 | |
| 3061 | FlatSet<ResourceId> JavaScriptRuntime::getAllUsedModules() const { |
| 3062 | FlatSet<ResourceId> allUsedModules; |
| 3063 | for (const auto& context : _contextManager->getAllContexts()) { |
| 3064 | allUsedModules.insert(context->getPath().getResourceId()); |
| 3065 | } |
| 3066 | for (const auto& it : _modules) { |
| 3067 | allUsedModules.insert(it.first); |
| 3068 | } |
| 3069 | return allUsedModules; |
| 3070 | } |
| 3071 | |
| 3072 | bool JavaScriptRuntime::unloadNextUnusedModule(JavaScriptEntryParameters& entry) { |
| 3073 | auto allUsedModules = getAllUsedModules(); |
| 3074 | |
| 3075 | auto allUsedModulesArray = ValueArray::make(allUsedModules.size()); |
| 3076 | size_t i = 0; |
| 3077 | for (const auto& resId : allUsedModules) { |
| 3078 | allUsedModulesArray->emplace(i++, Value(StringCache::getGlobal().makeString(resId.toAbsolutePath()))); |
| 3079 | } |
| 3080 | |
| 3081 | auto allUsedModulesJs = |
no test coverage detected