// Copyright 2015 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include "src/asmjs/asm-js.h" #include "src/assembler-inl.h" #include "src/base/atomic-utils.h" #include "src/base/utils/random-number-generator.h" #include "src/code-stubs.h" #include "src/compiler/wasm-compiler.h" #include "src/debug/interface-types.h" #include "src/frames-inl.h" #include "src/objects.h" #include "src/property-descriptor.h" #include "src/simulator.h" #include "src/snapshot/snapshot.h" #include "src/trap-handler/trap-handler.h" #include "src/v8.h" #include "src/wasm/function-body-decoder.h" #include "src/wasm/module-decoder.h" #include "src/wasm/wasm-code-specialization.h" #include "src/wasm/wasm-js.h" #include "src/wasm/wasm-limits.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects.h" #include "src/wasm/wasm-result.h" using namespace v8::internal; using namespace v8::internal::wasm; namespace base = v8::base; #define TRACE(...) \ do { \ if (FLAG_trace_wasm_instances) PrintF(__VA_ARGS__); \ } while (false) #define TRACE_CHAIN(instance) \ do { \ instance->PrintInstancesChain(); \ } while (false) #define TRACE_COMPILE(...) \ do { \ if (FLAG_trace_wasm_compiler) PrintF(__VA_ARGS__); \ } while (false) namespace { static const int kInvalidSigIndex = -1; byte* raw_buffer_ptr(MaybeHandle buffer, int offset) { return static_cast(buffer.ToHandleChecked()->backing_store()) + offset; } static void RecordStats(Isolate* isolate, Code* code, bool is_sync) { if (is_sync) { // TODO(karlschimpf): Make this work when asynchronous. // https://bugs.chromium.org/p/v8/issues/detail?id=6361 isolate->counters()->wasm_generated_code_size()->Increment( code->body_size()); isolate->counters()->wasm_reloc_size()->Increment( code->relocation_info()->length()); } } static void RecordStats(Isolate* isolate, Handle functions, bool is_sync) { DisallowHeapAllocation no_gc; for (int i = 0; i < functions->length(); ++i) { RecordStats(isolate, Code::cast(functions->get(i)), is_sync); } } void* TryAllocateBackingStore(Isolate* isolate, size_t size, bool enable_guard_regions, void*& allocation_base, size_t& allocation_length) { // TODO(eholk): Right now enable_guard_regions has no effect on 32-bit // systems. It may be safer to fail instead, given that other code might do // things that would be unsafe if they expected guard pages where there // weren't any. if (enable_guard_regions && kGuardRegionsSupported) { // TODO(eholk): On Windows we want to make sure we don't commit the guard // pages yet. // We always allocate the largest possible offset into the heap, so the // addressable memory after the guard page can be made inaccessible. allocation_length = RoundUp(kWasmMaxHeapOffset, base::OS::CommitPageSize()); DCHECK_EQ(0, size % base::OS::CommitPageSize()); // AllocateGuarded makes the whole region inaccessible by default. allocation_base = isolate->array_buffer_allocator()->Reserve(allocation_length); if (allocation_base == nullptr) { return nullptr; } void* memory = allocation_base; // Make the part we care about accessible. isolate->array_buffer_allocator()->SetProtection( memory, size, v8::ArrayBuffer::Allocator::Protection::kReadWrite); reinterpret_cast(isolate) ->AdjustAmountOfExternalAllocatedMemory(size); return memory; } else { void* memory = isolate->array_buffer_allocator()->Allocate(size); allocation_base = memory; allocation_length = size; return memory; } } void FlushICache(Isolate* isolate, Handle code_table) { for (int i = 0; i < code_table->length(); ++i) { Handle code = code_table->GetValueChecked(isolate, i); Assembler::FlushICache(isolate, code->instruction_start(), code->instruction_size()); } } Handle