[heap] Add tests to CodeBuilder Build and TryBuild

Bug: chromium:957934
Change-Id: Ia1ce5f6150b7f862b38f4c135236b154a1b02d6c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1594564
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Commit-Queue: Maciej Goszczycki <goszczycki@google.com>
Cr-Commit-Position: refs/heads/master@{#61391}
diff --git a/test/cctest/test-factory.cc b/test/cctest/test-factory.cc
index 3c644cb..0560c5b 100644
--- a/test/cctest/test-factory.cc
+++ b/test/cctest/test-factory.cc
@@ -13,11 +13,45 @@
 namespace internal {
 namespace test_factory {
 
+namespace {
+
+constexpr int kInstructionSize = 10 * MB;
+
+size_t NearHeapLimitCallback(void* raw_bool, size_t current_heap_limit,
+                             size_t initial_heap_limit) {
+  bool* oom_triggered = static_cast<bool*>(raw_bool);
+  *oom_triggered = true;
+  return kInstructionSize * 2;
+}
+
+class SetupIsolateWithSmallHeap {
+ public:
+  SetupIsolateWithSmallHeap() {
+    FLAG_max_old_space_size = kInstructionSize / MB / 2;  // In MB.
+    v8::Isolate::CreateParams create_params;
+    create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+    isolate_ = reinterpret_cast<Isolate*>(v8::Isolate::New(create_params));
+    isolate_->heap()->AddNearHeapLimitCallback(NearHeapLimitCallback,
+                                               &oom_triggered_);
+  }
+
+  ~SetupIsolateWithSmallHeap() {
+    reinterpret_cast<v8::Isolate*>(isolate_)->Dispose();
+  }
+
+  Isolate* isolate() { return isolate_; }
+  bool oom_triggered() const { return oom_triggered_; }
+
+ private:
+  Isolate* isolate_;
+  bool oom_triggered_ = false;
+};
+
+}  // namespace
+
 TEST(Factory_CodeBuilder) {
-  LocalContext env;
-  v8::Isolate* isolate = env->GetIsolate();
-  Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
-  HandleScope scope(i_isolate);
+  Isolate* isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
 
   // Create a big function that ends up in CODE_LO_SPACE.
   const int instruction_size = kMaxRegularHeapObjectSize + 1;
@@ -33,14 +67,46 @@
   desc.unwinding_info_size = 0;
   desc.origin = nullptr;
   Handle<Code> code =
-      Factory::CodeBuilder(i_isolate, desc, Code::WASM_FUNCTION).Build();
+      Factory::CodeBuilder(isolate, desc, Code::WASM_FUNCTION).Build();
 
-  CHECK(i_isolate->heap()->InSpace(*code, CODE_LO_SPACE));
+  CHECK(isolate->heap()->InSpace(*code, CODE_LO_SPACE));
 #if VERIFY_HEAP
-  code->ObjectVerify(i_isolate);
+  code->ObjectVerify(isolate);
 #endif
 }
 
+UNINITIALIZED_TEST(Factory_CodeBuilder_BuildOOM) {
+  SetupIsolateWithSmallHeap isolate_scope;
+  HandleScope scope(isolate_scope.isolate());
+  std::unique_ptr<byte[]> instructions(new byte[kInstructionSize]);
+  CodeDesc desc;
+  desc.instr_size = kInstructionSize;
+  desc.buffer = instructions.get();
+
+  const Handle<Code> code =
+      Factory::CodeBuilder(isolate_scope.isolate(), desc, Code::WASM_FUNCTION)
+          .Build();
+
+  CHECK(!code.is_null());
+  CHECK(isolate_scope.oom_triggered());
+}
+
+UNINITIALIZED_TEST(Factory_CodeBuilder_TryBuildOOM) {
+  SetupIsolateWithSmallHeap isolate_scope;
+  HandleScope scope(isolate_scope.isolate());
+  std::unique_ptr<byte[]> instructions(new byte[kInstructionSize]);
+  CodeDesc desc;
+  desc.instr_size = kInstructionSize;
+  desc.buffer = instructions.get();
+
+  const MaybeHandle<Code> code =
+      Factory::CodeBuilder(isolate_scope.isolate(), desc, Code::WASM_FUNCTION)
+          .TryBuild();
+
+  CHECK(code.is_null());
+  CHECK(!isolate_scope.oom_triggered());
+}
+
 }  // namespace test_factory
 }  // namespace internal
 }  // namespace v8