Backed out changeset d537051ade6a (bug 1315510) for nsTArray_base leaks and a fondess for crashing

CLOSED TREE

MozReview-Commit-ID: KD3jAkCg0O7
This commit is contained in:
Phil Ringnalda 2016-11-07 22:18:21 -08:00
Родитель 6c8fce2953
Коммит 27a5b8d2ae
12 изменённых файлов: 104 добавлений и 151 удалений

Просмотреть файл

@ -25,7 +25,6 @@
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
#include "mozilla/dom/ContentBridgeChild.h"
#include "mozilla/dom/ContentBridgeParent.h"
#include "mozilla/dom/VideoDecoderManagerChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/DataTransfer.h"
#include "mozilla/dom/DOMStorageIPC.h"
@ -1182,8 +1181,7 @@ ContentChild::RecvGMPsChanged(nsTArray<GMPCapabilityData>&& capabilities)
bool
ContentChild::RecvInitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager)
Endpoint<PVRManagerChild>&& aVRBridge)
{
if (!CompositorBridgeChild::InitForContent(Move(aCompositor))) {
return false;
@ -1194,15 +1192,13 @@ ContentChild::RecvInitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
if (!gfx::VRManagerChild::InitForContent(Move(aVRBridge))) {
return false;
}
VideoDecoderManagerChild::InitForContent(Move(aVideoManager));
return true;
}
bool
ContentChild::RecvReinitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager)
Endpoint<PVRManagerChild>&& aVRBridge)
{
nsTArray<RefPtr<TabChild>> tabs = TabChild::GetAll();
@ -1230,8 +1226,6 @@ ContentChild::RecvReinitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor
tabChild->ReinitRendering();
}
}
VideoDecoderManagerChild::InitForContent(Move(aVideoManager));
return true;
}

Просмотреть файл

@ -169,15 +169,13 @@ public:
RecvInitRendering(
Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
Endpoint<PVRManagerChild>&& aVRBridge) override;
bool
RecvReinitRendering(
Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
Endpoint<PVRManagerChild>&& aVRBridge) override;
PProcessHangMonitorChild*
AllocPProcessHangMonitorChild(Transport* aTransport,

Просмотреть файл

@ -1027,6 +1027,13 @@ ContentParent::RecvFindPlugins(const uint32_t& aPluginEpoch,
return true;
}
bool
ContentParent::RecvInitVideoDecoderManager(Endpoint<PVideoDecoderManagerChild>* aEndpoint)
{
GPUProcessManager::Get()->CreateContentVideoDecoderManager(OtherPid(), aEndpoint);
return true;
}
/*static*/ TabParent*
ContentParent::CreateBrowserOrApp(const TabContext& aContext,
Element* aFrameElement,
@ -2220,21 +2227,18 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
Endpoint<PCompositorBridgeChild> compositor;
Endpoint<PImageBridgeChild> imageBridge;
Endpoint<PVRManagerChild> vrBridge;
Endpoint<PVideoDecoderManagerChild> videoManager;
DebugOnly<bool> opened = gpm->CreateContentBridges(
OtherPid(),
&compositor,
&imageBridge,
&vrBridge,
&videoManager);
&vrBridge);
MOZ_ASSERT(opened);
Unused << SendInitRendering(
Move(compositor),
Move(imageBridge),
Move(vrBridge),
Move(videoManager));
Move(vrBridge));
gpm->AddListener(this);
}
@ -2379,21 +2383,18 @@ ContentParent::OnCompositorUnexpectedShutdown()
Endpoint<PCompositorBridgeChild> compositor;
Endpoint<PImageBridgeChild> imageBridge;
Endpoint<PVRManagerChild> vrBridge;
Endpoint<PVideoDecoderManagerChild> videoManager;
DebugOnly<bool> opened = gpm->CreateContentBridges(
OtherPid(),
&compositor,
&imageBridge,
&vrBridge,
&videoManager);
&vrBridge);
MOZ_ASSERT(opened);
Unused << SendReinitRendering(
Move(compositor),
Move(imageBridge),
Move(vrBridge),
Move(videoManager));
Move(vrBridge));
}
void

Просмотреть файл

@ -262,6 +262,8 @@ public:
nsTArray<PluginTag>* aPlugins,
uint32_t* aNewPluginEpoch) override;
virtual bool RecvInitVideoDecoderManager(Endpoint<PVideoDecoderManagerChild>* endpoint) override;
virtual bool RecvUngrabPointer(const uint32_t& aTime) override;
virtual bool RecvRemovePermission(const IPC::Principal& aPrincipal,

Просмотреть файл

@ -429,8 +429,7 @@ child:
async InitRendering(
Endpoint<PCompositorBridgeChild> compositor,
Endpoint<PImageBridgeChild> imageBridge,
Endpoint<PVRManagerChild> vr,
Endpoint<PVideoDecoderManagerChild> video);
Endpoint<PVRManagerChild> vr);
// Re-create the rendering stack using the given endpoints. This is sent
// after the compositor process has crashed. The new endpoints may be to a
@ -438,8 +437,7 @@ child:
async ReinitRendering(
Endpoint<PCompositorBridgeChild> compositor,
Endpoint<PImageBridgeChild> bridge,
Endpoint<PVRManagerChild> vr,
Endpoint<PVideoDecoderManagerChild> video);
Endpoint<PVRManagerChild> vr);
/**
* Enable system-level sandboxing features, if available. Can
@ -744,6 +742,8 @@ parent:
sync PCrashReporter(NativeThreadId tid, uint32_t processType);
sync InitVideoDecoderManager() returns (Endpoint<PVideoDecoderManagerChild> endpoint);
/**
* Is this token compatible with the provided version?
*

Просмотреть файл

@ -9,7 +9,6 @@
#include "mozilla/layers/TextureClient.h"
#include "base/thread.h"
#include "MediaInfo.h"
#include "MediaPrefs.h"
#include "ImageContainer.h"
namespace mozilla {
@ -148,8 +147,7 @@ RemoteDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
already_AddRefed<MediaDataDecoder>
RemoteDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
{
if (!MediaPrefs::PDMUseGPUDecoder() ||
!aParams.mKnowsCompositor ||
if (!aParams.mKnowsCompositor ||
aParams.mKnowsCompositor->GetTextureFactoryIdentifier().mParentProcessType != GeckoProcessType_GPU) {
return nullptr;
}

Просмотреть файл

@ -103,16 +103,11 @@ void
VideoDecoderChild::ActorDestroy(ActorDestroyReason aWhy)
{
if (aWhy == AbnormalShutdown) {
// Defer reporting an error until we've recreated the manager so that
// it'll be safe for MediaFormatReader to recreate decoders
RefPtr<VideoDecoderChild> ref = this;
GetManager()->RunWhenRecreated(NS_NewRunnableFunction([=]() {
if (ref->mInitialized) {
ref->mCallback->Error(NS_ERROR_DOM_MEDIA_DECODE_ERR);
} else {
ref->mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
}
}));
if (mInitialized) {
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
} else {
mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
}
}
mCanSend = false;
}
@ -123,15 +118,9 @@ VideoDecoderChild::InitIPDL(MediaDataDecoderCallback* aCallback,
layers::KnowsCompositor* aKnowsCompositor)
{
RefPtr<VideoDecoderManagerChild> manager = VideoDecoderManagerChild::GetSingleton();
// If the manager isn't available, then don't initialize mIPDLSelfRef and leave
// us in an error state. We'll then immediately reject the promise when Init()
// is called and the caller can try again. Hopefully by then the new manager is
// ready, or we've notified the caller of it being no longer available.
// If not, then the cycle repeats until we're ready.
if (!manager || !manager->CanSend()) {
if (!manager) {
return;
}
mIPDLSelfRef = this;
mCallback = aCallback;
mVideoInfo = aVideoInfo;
@ -161,15 +150,9 @@ RefPtr<MediaDataDecoder::InitPromise>
VideoDecoderChild::Init()
{
AssertOnManagerThread();
if (!mIPDLSelfRef) {
if (!mCanSend || !SendInit(mVideoInfo, mKnowsCompositor->GetTextureFactoryIdentifier())) {
return MediaDataDecoder::InitPromise::CreateAndReject(
NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
}
// If we failed to send this, then we'll still resolve the Init promise
// as ActorDestroy handles it.
if (mCanSend) {
SendInit(mVideoInfo, mKnowsCompositor->GetTextureFactoryIdentifier());
NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
}
return mInitPromise.Ensure(__func__);
}
@ -179,6 +162,7 @@ VideoDecoderChild::Input(MediaRawData* aSample)
{
AssertOnManagerThread();
if (!mCanSend) {
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
return;
}
@ -187,7 +171,7 @@ VideoDecoderChild::Input(MediaRawData* aSample)
// into shmem rather than requiring a copy here.
Shmem buffer;
if (!AllocShmem(aSample->Size(), Shmem::SharedMemory::TYPE_BASIC, &buffer)) {
mCallback->Error(NS_ERROR_DOM_MEDIA_DECODE_ERR);
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
return;
}
@ -200,15 +184,17 @@ VideoDecoderChild::Input(MediaRawData* aSample)
aSample->mFrames,
aSample->mKeyframe),
buffer);
SendInput(sample);
if (!SendInput(sample)) {
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
}
}
void
VideoDecoderChild::Flush()
{
AssertOnManagerThread();
if (mCanSend) {
SendFlush();
if (!mCanSend || !SendFlush()) {
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
}
}
@ -216,8 +202,8 @@ void
VideoDecoderChild::Drain()
{
AssertOnManagerThread();
if (mCanSend) {
SendDrain();
if (!mCanSend || !SendDrain()) {
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
}
}
@ -225,8 +211,8 @@ void
VideoDecoderChild::Shutdown()
{
AssertOnManagerThread();
if (mCanSend) {
SendShutdown();
if (!mCanSend || !SendShutdown()) {
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
}
mInitialized = false;
}
@ -242,8 +228,8 @@ void
VideoDecoderChild::SetSeekThreshold(const media::TimeUnit& aTime)
{
AssertOnManagerThread();
if (mCanSend) {
SendSetSeekThreshold(aTime.ToMicroseconds());
if (!mCanSend || !SendSetSeekThreshold(aTime.ToMicroseconds())) {
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
}
}

Просмотреть файл

@ -13,7 +13,6 @@
#include "mozilla/layers/SynchronousTask.h"
#include "mozilla/gfx/DataSurfaceHelpers.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "base/task.h"
namespace mozilla {
namespace dom {
@ -28,13 +27,24 @@ StaticRefPtr<AbstractThread> sVideoDecoderChildAbstractThread;
// Only accessed from sVideoDecoderChildThread
static StaticRefPtr<VideoDecoderManagerChild> sDecoderManager;
static nsTArray<RefPtr<Runnable>> sRecreateTasks;
/* static */ void
VideoDecoderManagerChild::InitializeThread()
VideoDecoderManagerChild::Initialize()
{
MOZ_ASSERT(NS_IsMainThread());
MediaPrefs::GetSingleton();
#ifdef XP_WIN
if (!MediaPrefs::PDMUseGPUDecoder()) {
return;
}
// Can't run remote video decoding in the parent process.
if (!ContentChild::GetSingleton()) {
return;
}
if (!sVideoDecoderChildThread) {
RefPtr<nsIThread> childThread;
nsresult rv = NS_NewNamedThread("VideoChild", getter_AddRefs(childThread));
@ -44,13 +54,10 @@ VideoDecoderManagerChild::InitializeThread()
sVideoDecoderChildAbstractThread =
AbstractThread::CreateXPCOMThreadWrapper(childThread, false);
}
}
#else
return;
#endif
/* static */ void
VideoDecoderManagerChild::InitForContent(Endpoint<PVideoDecoderManagerChild>&& aVideoManager)
{
InitializeThread();
sVideoDecoderChildThread->Dispatch(NewRunnableFunction(&Open, Move(aVideoManager)), NS_DISPATCH_NORMAL);
}
/* static */ void
@ -60,7 +67,7 @@ VideoDecoderManagerChild::Shutdown()
if (sVideoDecoderChildThread) {
sVideoDecoderChildThread->Dispatch(NS_NewRunnableFunction([]() {
if (sDecoderManager && sDecoderManager->CanSend()) {
if (sDecoderManager) {
sDecoderManager->Close();
sDecoderManager = nullptr;
}
@ -72,25 +79,33 @@ VideoDecoderManagerChild::Shutdown()
}
}
void
VideoDecoderManagerChild::RunWhenRecreated(already_AddRefed<Runnable> aTask)
{
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
// If we've already been recreated, then run the task immediately.
if (sDecoderManager && sDecoderManager != this && sDecoderManager->CanSend()) {
RefPtr<Runnable> task = aTask;
task->Run();
} else {
sRecreateTasks.AppendElement(aTask);
}
}
/* static */ VideoDecoderManagerChild*
VideoDecoderManagerChild::GetSingleton()
{
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
if (!sDecoderManager || !sDecoderManager->mCanSend) {
RefPtr<VideoDecoderManagerChild> manager;
NS_DispatchToMainThread(NS_NewRunnableFunction([&]() {
Endpoint<PVideoDecoderManagerChild> endpoint;
if (!ContentChild::GetSingleton()->SendInitVideoDecoderManager(&endpoint)) {
return;
}
if (!endpoint.IsValid()) {
return;
}
manager = new VideoDecoderManagerChild();
RefPtr<Runnable> task = NewRunnableMethod<Endpoint<PVideoDecoderManagerChild>&&>(
manager, &VideoDecoderManagerChild::Open, Move(endpoint));
sVideoDecoderChildThread->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}), NS_DISPATCH_SYNC);
sDecoderManager = manager;
}
return sDecoderManager;
}
@ -123,27 +138,11 @@ VideoDecoderManagerChild::DeallocPVideoDecoderChild(PVideoDecoderChild* actor)
void
VideoDecoderManagerChild::Open(Endpoint<PVideoDecoderManagerChild>&& aEndpoint)
{
// Make sure we always dispatch everything in sRecreateTasks, even if we
// fail since this is as close to being recreated as we will ever be.
sDecoderManager = nullptr;
if (aEndpoint.IsValid()) {
RefPtr<VideoDecoderManagerChild> manager = new VideoDecoderManagerChild();
if (aEndpoint.Bind(manager)) {
sDecoderManager = manager;
manager->InitIPDL();
}
if (!aEndpoint.Bind(this)) {
return;
}
for (Runnable* task : sRecreateTasks) {
task->Run();
}
sRecreateTasks.Clear();
}
void
VideoDecoderManagerChild::InitIPDL()
{
AddRef();
mCanSend = true;
mIPDLSelfRef = this;
}
void
@ -155,14 +154,7 @@ VideoDecoderManagerChild::ActorDestroy(ActorDestroyReason aWhy)
void
VideoDecoderManagerChild::DeallocPVideoDecoderManagerChild()
{
mIPDLSelfRef = nullptr;
}
bool
VideoDecoderManagerChild::CanSend()
{
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
return mCanSend;
Release();
}
bool
@ -172,7 +164,7 @@ VideoDecoderManagerChild::DeallocShmem(mozilla::ipc::Shmem& aShmem)
RefPtr<VideoDecoderManagerChild> self = this;
mozilla::ipc::Shmem shmem = aShmem;
sVideoDecoderChildThread->Dispatch(NS_NewRunnableFunction([self, shmem]() {
if (self->CanSend()) {
if (self->mCanSend) {
mozilla::ipc::Shmem shmemCopy = shmem;
self->DeallocShmem(shmemCopy);
}
@ -215,7 +207,7 @@ VideoDecoderManagerChild::Readback(const SurfaceDescriptorGPUVideo& aSD)
SurfaceDescriptor sd;
sVideoDecoderChildThread->Dispatch(NS_NewRunnableFunction([&]() {
AutoCompleteTask complete(&task);
if (ref->CanSend()) {
if (ref->mCanSend) {
ref->SendReadback(aSD, &sd);
}
}), NS_DISPATCH_NORMAL);
@ -247,7 +239,7 @@ VideoDecoderManagerChild::DeallocateSurfaceDescriptorGPUVideo(const SurfaceDescr
RefPtr<VideoDecoderManagerChild> ref = this;
SurfaceDescriptorGPUVideo sd = Move(aSD);
sVideoDecoderChildThread->Dispatch(NS_NewRunnableFunction([ref, sd]() {
if (ref->CanSend()) {
if (ref->mCanSend) {
ref->SendDeallocateSurfaceDescriptorGPUVideo(sd);
}
}), NS_DISPATCH_NORMAL);

Просмотреть файл

@ -51,20 +51,10 @@ public:
bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
// Main thread only
static void InitForContent(Endpoint<PVideoDecoderManagerChild>&& aVideoManager);
static void Initialize();
static void Shutdown();
// Run aTask (on the manager thread) when we next attempt to create a new manager
// (even if creation fails). Intended to be called from ActorDestroy when we get
// notified that the old manager is being destroyed.
// Can only be called from the manager thread.
void RunWhenRecreated(already_AddRefed<Runnable> aTask);
bool CanSend();
protected:
void InitIPDL();
void ActorDestroy(ActorDestroyReason aWhy) override;
void DeallocPVideoDecoderManagerChild() override;
@ -74,17 +64,12 @@ protected:
bool DeallocPVideoDecoderChild(PVideoDecoderChild* actor) override;
private:
// Main thread only
static void InitializeThread();
VideoDecoderManagerChild()
: mCanSend(false)
{}
~VideoDecoderManagerChild() {}
static void Open(Endpoint<PVideoDecoderManagerChild>&& aEndpoint);
RefPtr<VideoDecoderManagerChild> mIPDLSelfRef;
void Open(Endpoint<PVideoDecoderManagerChild>&& aEndpoint);
// Should only ever be accessed on the manager thread.
bool mCanSend;

Просмотреть файл

@ -29,7 +29,6 @@
#include "VsyncSource.h"
#include "mozilla/dom/VideoDecoderManagerChild.h"
#include "mozilla/dom/VideoDecoderManagerParent.h"
#include "MediaPrefs.h"
namespace mozilla {
namespace gfx {
@ -537,8 +536,7 @@ bool
GPUProcessManager::CreateContentBridges(base::ProcessId aOtherProcess,
ipc::Endpoint<PCompositorBridgeChild>* aOutCompositor,
ipc::Endpoint<PImageBridgeChild>* aOutImageBridge,
ipc::Endpoint<PVRManagerChild>* aOutVRBridge,
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutVideoManager)
ipc::Endpoint<PVRManagerChild>* aOutVRBridge)
{
if (!CreateContentCompositorBridge(aOtherProcess, aOutCompositor) ||
!CreateContentImageBridge(aOtherProcess, aOutImageBridge) ||
@ -546,9 +544,6 @@ GPUProcessManager::CreateContentBridges(base::ProcessId aOtherProcess,
{
return false;
}
// VideoDeocderManager is only supported in the GPU process, so we allow this to be
// fallible.
CreateContentVideoDecoderManager(aOtherProcess, aOutVideoManager);
return true;
}
@ -664,12 +659,12 @@ GPUProcessManager::CreateContentVRManager(base::ProcessId aOtherProcess,
return true;
}
void
bool
GPUProcessManager::CreateContentVideoDecoderManager(base::ProcessId aOtherProcess,
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndpoint)
{
if (!mGPUChild || !MediaPrefs::PDMUseGPUDecoder()) {
return;
if (!mGPUChild) {
return false;
}
ipc::Endpoint<dom::PVideoDecoderManagerParent> parentPipe;
@ -682,13 +677,13 @@ GPUProcessManager::CreateContentVideoDecoderManager(base::ProcessId aOtherProces
&childPipe);
if (NS_FAILED(rv)) {
gfxCriticalNote << "Could not create content video decoder: " << hexa(int(rv));
return;
return false;
}
mGPUChild->SendNewContentVideoDecoderManager(Move(parentPipe));
*aOutEndpoint = Move(childPipe);
return;
return true;
}
already_AddRefed<IAPZCTreeManager>

Просмотреть файл

@ -92,8 +92,9 @@ public:
base::ProcessId aOtherProcess,
ipc::Endpoint<PCompositorBridgeChild>* aOutCompositor,
ipc::Endpoint<PImageBridgeChild>* aOutImageBridge,
ipc::Endpoint<PVRManagerChild>* aOutVRBridge,
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutVideoManager);
ipc::Endpoint<PVRManagerChild>* aOutVRBridge);
bool CreateContentVideoDecoderManager(base::ProcessId aOtherProcess,
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndPoint);
// This returns a reference to the APZCTreeManager to which
// pan/zoom-related events can be sent.
@ -158,8 +159,6 @@ private:
ipc::Endpoint<PImageBridgeChild>* aOutEndpoint);
bool CreateContentVRManager(base::ProcessId aOtherProcess,
ipc::Endpoint<PVRManagerChild>* aOutEndpoint);
void CreateContentVideoDecoderManager(base::ProcessId aOtherProcess,
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndPoint);
// Called from RemoteCompositorSession. We track remote sessions so we can
// notify their owning widgets that the session must be restarted.

Просмотреть файл

@ -67,6 +67,7 @@
#include "FrameLayerBuilder.h"
#include "AnimationCommon.h"
#include "LayerAnimationInfo.h"
#include "mozilla/dom/VideoDecoderManagerChild.h"
#include "AudioChannelService.h"
#include "mozilla/dom/PromiseDebugging.h"
@ -301,6 +302,8 @@ nsLayoutStatics::Initialize()
MediaDecoder::InitStatics();
VideoDecoderManagerChild::Initialize();
PromiseDebugging::Init();
mozilla::dom::devicestorage::DeviceStorageStatics::Initialize();