1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ecmascript/ecma_vm.h"
17 #include "ecmascript/js_handle.h"
18 #include "ecmascript/mem/mem_common.h"
19 #include "ecmascript/mem/space.h"
20 #include "ecmascript/object_factory.h"
21 #include "ecmascript/tagged_array-inl.h"
22 #include "ecmascript/tests/test_helper.h"
23 
24 using namespace panda::ecmascript;
25 
26 namespace panda::test {
27 class ThrowOOMErrorTest : public BaseTestWithScope<false> {
28 public:
29     void SetUp() override
30     {
31         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
32         thread->GetEcmaVM()->SetEnableForceGC(false);
33         const_cast<Heap *>(thread->GetEcmaVM()->GetHeap())->SetMarkType(MarkType::MARK_FULL);
34     }
35 };
36 
HWTEST_F_L0(ThrowOOMErrorTest, ThrowNonMovableOOMError)37 HWTEST_F_L0(ThrowOOMErrorTest, ThrowNonMovableOOMError)
38 {
39 #ifdef NDEBUG
40     static constexpr size_t SIZE = 100_KB / 8;
41     [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
42     for (int i = 0; i < 800; i++) {
43         [[maybe_unused]] JSHandle<TaggedArray> array =
44             thread->GetEcmaVM()->GetFactory()->NewTaggedArray(SIZE, JSTaggedValue::Hole(), MemSpaceType::NON_MOVABLE);
45     }
46 
47     EXPECT_TRUE(thread->HasPendingException());
48     JSType errorType = thread->GetException().GetTaggedObject()->GetClass()->GetObjectType();
49     EXPECT_EQ(errorType, JSType::JS_OOM_ERROR);
50 #endif
51 }
52 
HWTEST_F_L0(ThrowOOMErrorTest, ThrowOldSpaceMergeOOMError)53 HWTEST_F_L0(ThrowOOMErrorTest, ThrowOldSpaceMergeOOMError)
54 {
55     auto ecmaVm = thread->GetEcmaVM();
56     auto heap = const_cast<Heap *>(ecmaVm->GetHeap());
57     auto oldSpace = heap->GetOldSpace();
58     oldSpace->SetMaximumCapacity(6_MB);
59 
60     static constexpr size_t SIZE = 100_KB / 8;
61     [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
62 
63     for (int i = 0; i < 46; i++) {
64         [[maybe_unused]] JSHandle<TaggedArray> array =
65             thread->GetEcmaVM()->GetFactory()->NewTaggedArray(SIZE, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE);
66     }
67 
68     EXPECT_TRUE(!thread->HasPendingException());
69 
70     for (int i = 0; i < 4; i++) {
71         [[maybe_unused]] JSHandle<TaggedArray> array =
72             thread->GetEcmaVM()->GetFactory()->NewTaggedArray(SIZE, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE);
73     }
74 
75     heap->CollectGarbage(TriggerGCType::YOUNG_GC);
76     heap->Prepare();
77     heap->CollectGarbage(TriggerGCType::YOUNG_GC);
78     heap->Prepare();
79 
80     EXPECT_TRUE(thread->HasPendingException());
81     JSType errorType = thread->GetException().GetTaggedObject()->GetClass()->GetObjectType();
82     EXPECT_EQ(errorType, JSType::JS_OOM_ERROR);
83 }
84 }  // namespace panda::test
85