diff options
author | Vladimir Marko <vmarko@google.com> | 2014-05-02 14:40:15 +0100 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2014-05-13 11:43:22 +0100 |
commit | 7624d25dad2d1ba25969ae704fccf68649103ae5 (patch) | |
tree | de72194b76a4e23e0b15ec4085447ae7e4425815 /compiler | |
parent | e1910f1d802dff79bba5ef61e1c4fd0b95f6e5b0 (diff) | |
download | android_art-7624d25dad2d1ba25969ae704fccf68649103ae5.tar.gz android_art-7624d25dad2d1ba25969ae704fccf68649103ae5.tar.bz2 android_art-7624d25dad2d1ba25969ae704fccf68649103ae5.zip |
Move quick frame info to OatQuickMethodHeader.
Rename OatMethodHeader to OatQuickMethodHeader, move frame
info from OatMethodOffsets to OatQuickMethodHeader. Retrieve
the info from other places for non-quick methods (portable
compiled bytecode or jni stub, generic jni, runtime,
abstract and proxy).
This change has a libcore/ companion CL
"Remove ArtMethod's quick fields for frame size and spills."
https://android-review.googlesource.com/94164
Bug: 11767815
Change-Id: I0e31a7875d76732e1ec479c86b9b5ca01203507f
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/common_compiler_test.h | 45 | ||||
-rw-r--r-- | compiler/jni/quick/x86_64/calling_convention_x86_64.cc | 2 | ||||
-rw-r--r-- | compiler/oat_test.cc | 8 | ||||
-rw-r--r-- | compiler/oat_writer.cc | 98 | ||||
-rw-r--r-- | compiler/oat_writer.h | 2 |
5 files changed, 51 insertions, 104 deletions
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h index 8bba84a9c1..8f39212b80 100644 --- a/compiler/common_compiler_test.h +++ b/compiler/common_compiler_test.h @@ -134,9 +134,6 @@ class CommonCompilerTest : public CommonRuntimeTest { public: // Create an OatMethod based on pointers (for unit tests). OatFile::OatMethod CreateOatMethod(const void* code, - const size_t frame_size_in_bytes, - const uint32_t core_spill_mask, - const uint32_t fp_spill_mask, const uint8_t* gc_map) { CHECK(code != nullptr); const byte* base; @@ -154,9 +151,6 @@ class CommonCompilerTest : public CommonRuntimeTest { } return OatFile::OatMethod(base, code_offset, - frame_size_in_bytes, - core_spill_mask, - fp_spill_mask, gc_map_offset); } @@ -179,11 +173,14 @@ class CommonCompilerTest : public CommonRuntimeTest { CHECK_NE(0u, code_size); const std::vector<uint8_t>& vmap_table = compiled_method->GetVmapTable(); uint32_t vmap_table_offset = vmap_table.empty() ? 0u - : sizeof(OatMethodHeader) + vmap_table.size(); + : sizeof(OatQuickMethodHeader) + vmap_table.size(); const std::vector<uint8_t>& mapping_table = compiled_method->GetMappingTable(); uint32_t mapping_table_offset = mapping_table.empty() ? 0u - : sizeof(OatMethodHeader) + vmap_table.size() + mapping_table.size(); - OatMethodHeader method_header(vmap_table_offset, mapping_table_offset, code_size); + : sizeof(OatQuickMethodHeader) + vmap_table.size() + mapping_table.size(); + OatQuickMethodHeader method_header(mapping_table_offset, vmap_table_offset, + compiled_method->GetFrameSizeInBytes(), + compiled_method->GetCoreSpillMask(), + compiled_method->GetFpSpillMask(), code_size); header_code_and_maps_chunks_.push_back(std::vector<uint8_t>()); std::vector<uint8_t>* chunk = &header_code_and_maps_chunks_.back(); @@ -207,11 +204,7 @@ class CommonCompilerTest : public CommonRuntimeTest { const void* method_code = CompiledMethod::CodePointer(code_ptr, compiled_method->GetInstructionSet()); LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code; - OatFile::OatMethod oat_method = CreateOatMethod(method_code, - compiled_method->GetFrameSizeInBytes(), - compiled_method->GetCoreSpillMask(), - compiled_method->GetFpSpillMask(), - nullptr); + OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr); oat_method.LinkMethod(method); method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge); } else { @@ -220,28 +213,13 @@ class CommonCompilerTest : public CommonRuntimeTest { if (!method->IsNative()) { const void* method_code = kUsePortableCompiler ? GetPortableToInterpreterBridge() : GetQuickToInterpreterBridge(); - OatFile::OatMethod oat_method = CreateOatMethod(method_code, - kStackAlignment, - 0, - 0, - nullptr); + OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr); oat_method.LinkMethod(method); method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge); } else { const void* method_code = GetQuickGenericJniTrampoline(); - mirror::ArtMethod* callee_save_method = runtime_->GetCalleeSaveMethod(Runtime::kRefsAndArgs); - - // Compute Sirt size, as Sirt goes into frame - MethodHelper mh(method); - uint32_t sirt_refs = mh.GetNumberOfReferenceArgsWithoutReceiver() + 1; - uint32_t sirt_size = StackIndirectReferenceTable::SizeOf(sirt_refs); - - OatFile::OatMethod oat_method = CreateOatMethod(method_code, - callee_save_method->GetFrameSizeInBytes() + - sirt_size, - callee_save_method->GetCoreSpillMask(), - callee_save_method->GetFpSpillMask(), - nullptr); + + OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr); oat_method.LinkMethod(method); method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge); } @@ -323,11 +301,12 @@ class CommonCompilerTest : public CommonRuntimeTest { compiler_options_->SetCompilerFilter(CompilerOptions::kInterpretOnly); #endif + runtime_->SetInstructionSet(instruction_set); for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i); if (!runtime_->HasCalleeSaveMethod(type)) { runtime_->SetCalleeSaveMethod( - runtime_->CreateCalleeSaveMethod(instruction_set, type), type); + runtime_->CreateCalleeSaveMethod(type), type); } } diff --git a/compiler/jni/quick/x86_64/calling_convention_x86_64.cc b/compiler/jni/quick/x86_64/calling_convention_x86_64.cc index 4dfa29a46f..52490e6e6b 100644 --- a/compiler/jni/quick/x86_64/calling_convention_x86_64.cc +++ b/compiler/jni/quick/x86_64/calling_convention_x86_64.cc @@ -133,7 +133,7 @@ X86_64JniCallingConvention::X86_64JniCallingConvention(bool is_static, bool is_s } uint32_t X86_64JniCallingConvention::CoreSpillMask() const { - return 1 << RBX | 1 << RBP | 1 << R12 | 1 << R13 | 1 << R14 | 1 << R15 | 1 << R13 | + return 1 << RBX | 1 << RBP | 1 << R12 | 1 << R13 | 1 << R14 | 1 << R15 | 1 << kNumberOfCpuRegisters; } diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index b5d39232ca..66972cbf69 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -17,11 +17,12 @@ #include "common_compiler_test.h" #include "compiler/compiler.h" #include "compiler/oat_writer.h" +#include "entrypoints/quick/quick_entrypoints.h" #include "mirror/art_method-inl.h" #include "mirror/class-inl.h" #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" -#include "oat_file.h" +#include "oat_file-inl.h" #include "vector_output_stream.h" namespace art { @@ -176,8 +177,9 @@ TEST_F(OatTest, OatHeaderSizeCheck) { // If this test is failing and you have to update these constants, // it is time to update OatHeader::kOatVersion EXPECT_EQ(80U, sizeof(OatHeader)); - EXPECT_EQ(20U, sizeof(OatMethodOffsets)); - EXPECT_EQ(12U, sizeof(OatMethodHeader)); + EXPECT_EQ(8U, sizeof(OatMethodOffsets)); + EXPECT_EQ(24U, sizeof(OatQuickMethodHeader)); + EXPECT_EQ(320U, sizeof(QuickEntryPoints)); } TEST_F(OatTest, OatHeaderIsValid) { diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index bbc9c3e325..39311d975b 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -331,9 +331,6 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { if (compiled_method != nullptr) { // Derived from CompiledMethod. uint32_t quick_code_offset = 0; - uint32_t frame_size_in_bytes = kStackAlignment; - uint32_t core_spill_mask = 0; - uint32_t fp_spill_mask = 0; const std::vector<uint8_t>* portable_code = compiled_method->GetPortableCode(); const std::vector<uint8_t>* quick_code = compiled_method->GetQuickCode(); @@ -351,7 +348,7 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { uint32_t code_size = quick_code->size() * sizeof(uint8_t); CHECK_NE(code_size, 0U); uint32_t thumb_offset = compiled_method->CodeDelta(); - quick_code_offset = offset_ + sizeof(OatMethodHeader) + thumb_offset; + quick_code_offset = offset_ + sizeof(OatQuickMethodHeader) + thumb_offset; std::vector<uint8_t>* cfi_info = writer_->compiler_driver_->GetCallFrameInformation(); if (cfi_info != nullptr) { @@ -374,27 +371,45 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { } } - DCHECK_LT(method_offsets_index_, oat_class->method_headers_.size()); - OatMethodHeader* method_header = &oat_class->method_headers_[method_offsets_index_]; - method_header->code_size_ = code_size; - // Deduplicate code arrays. auto code_iter = dedupe_map_.find(compiled_method); if (code_iter != dedupe_map_.end()) { quick_code_offset = code_iter->second; - FixupMethodHeader(method_header, quick_code_offset - thumb_offset); } else { dedupe_map_.Put(compiled_method, quick_code_offset); - FixupMethodHeader(method_header, quick_code_offset - thumb_offset); + } + + // Update quick method header. + DCHECK_LT(method_offsets_index_, oat_class->method_headers_.size()); + OatQuickMethodHeader* method_header = &oat_class->method_headers_[method_offsets_index_]; + uint32_t mapping_table_offset = method_header->mapping_table_offset_; + uint32_t vmap_table_offset = method_header->vmap_table_offset_; + // The code offset was 0 when the mapping/vmap table offset was set, so it's set + // to 0-offset and we need to adjust it by code_offset. + uint32_t code_offset = quick_code_offset - thumb_offset; + if (mapping_table_offset != 0u) { + mapping_table_offset += code_offset; + DCHECK_LT(mapping_table_offset, code_offset); + } + if (vmap_table_offset != 0u) { + vmap_table_offset += code_offset; + DCHECK_LT(vmap_table_offset, code_offset); + } + uint32_t frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); + uint32_t core_spill_mask = compiled_method->GetCoreSpillMask(); + uint32_t fp_spill_mask = compiled_method->GetFpSpillMask(); + *method_header = OatQuickMethodHeader(mapping_table_offset, vmap_table_offset, + frame_size_in_bytes, core_spill_mask, fp_spill_mask, + code_size); + + // Update checksum if this wasn't a duplicate. + if (code_iter == dedupe_map_.end()) { writer_->oat_header_->UpdateChecksum(method_header, sizeof(*method_header)); offset_ += sizeof(*method_header); // Method header is prepended before code. writer_->oat_header_->UpdateChecksum(&(*quick_code)[0], code_size); offset_ += code_size; } } - frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); - core_spill_mask = compiled_method->GetCoreSpillMask(); - fp_spill_mask = compiled_method->GetFpSpillMask(); if (kIsDebugBuild) { // We expect GC maps except when the class hasn't been verified or the method is native. @@ -421,9 +436,6 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { DCHECK_LT(method_offsets_index_, oat_class->method_offsets_.size()); OatMethodOffsets* offsets = &oat_class->method_offsets_[method_offsets_index_]; offsets->code_offset_ = quick_code_offset; - offsets->frame_size_in_bytes_ = frame_size_in_bytes; - offsets->core_spill_mask_ = core_spill_mask; - offsets->fp_spill_mask_ = fp_spill_mask; ++method_offsets_index_; } @@ -431,19 +443,6 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { } private: - static void FixupMethodHeader(OatMethodHeader* method_header, uint32_t code_offset) { - // The code offset was 0 when the mapping/vmap table offset was set, so it's set - // to 0-offset and we need to adjust it by code_offset. - if (method_header->mapping_table_offset_ != 0u) { - method_header->mapping_table_offset_ += code_offset; - DCHECK_LT(method_header->mapping_table_offset_, code_offset); - } - if (method_header->vmap_table_offset_ != 0u) { - method_header->vmap_table_offset_ += code_offset; - DCHECK_LT(method_header->vmap_table_offset_, code_offset); - } - } - // Deduplication is already done on a pointer basis by the compiler driver, // so we can simply compare the pointers to find out if things are duplicated. SafeMap<const CompiledMethod*, uint32_t, CodeOffsetsKeyComparator> dedupe_map_; @@ -501,55 +500,22 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor { OatClass* oat_class = writer_->oat_classes_[oat_class_index_]; CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index); - OatMethodOffsets offsets(0u, kStackAlignment, 0u, 0u, 0u); + OatMethodOffsets offsets(0u, 0u); if (compiled_method != nullptr) { DCHECK_LT(method_offsets_index_, oat_class->method_offsets_.size()); offsets = oat_class->method_offsets_[method_offsets_index_]; ++method_offsets_index_; } - // Derive frame size and spill masks for native methods without code: - // These are generic JNI methods... - uint32_t method_idx = it.GetMemberIndex(); - bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0; - if (is_native && compiled_method == nullptr) { - // Compute Sirt size as putting _every_ reference into it, even null ones. - uint32_t s_len; - const char* shorty = dex_file_->GetMethodShorty(dex_file_->GetMethodId(method_idx), - &s_len); - DCHECK(shorty != nullptr); - uint32_t refs = 1; // Native method always has "this" or class. - for (uint32_t i = 1; i < s_len; ++i) { - if (shorty[i] == 'L') { - refs++; - } - } - size_t pointer_size = GetInstructionSetPointerSize( - writer_->compiler_driver_->GetInstructionSet()); - size_t sirt_size = StackIndirectReferenceTable::GetAlignedSirtSizeTarget(pointer_size, refs); - - // Get the generic spill masks and base frame size. - mirror::ArtMethod* callee_save_method = - Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs); - - offsets.frame_size_in_bytes_ = callee_save_method->GetFrameSizeInBytes() + sirt_size; - offsets.core_spill_mask_ = callee_save_method->GetCoreSpillMask(); - offsets.fp_spill_mask_ = callee_save_method->GetFpSpillMask(); - DCHECK_EQ(offsets.gc_map_offset_, 0u); - } - ClassLinker* linker = Runtime::Current()->GetClassLinker(); InvokeType invoke_type = it.GetMethodInvokeType(dex_file_->GetClassDef(class_def_index_)); // Unchecked as we hold mutator_lock_ on entry. ScopedObjectAccessUnchecked soa(Thread::Current()); SirtRef<mirror::DexCache> dex_cache(soa.Self(), linker->FindDexCache(*dex_file_)); SirtRef<mirror::ClassLoader> class_loader(soa.Self(), nullptr); - mirror::ArtMethod* method = linker->ResolveMethod(*dex_file_, method_idx, dex_cache, + mirror::ArtMethod* method = linker->ResolveMethod(*dex_file_, it.GetMemberIndex(), dex_cache, class_loader, nullptr, invoke_type); CHECK(method != NULL); - method->SetFrameSizeInBytes(offsets.frame_size_in_bytes_); - method->SetCoreSpillMask(offsets.core_spill_mask_); - method->SetFpSpillMask(offsets.fp_spill_mask_); // Portable code offsets are set by ElfWriterMclinker::FixupCompiledCodeOffset after linking. method->SetQuickOatCodeOffset(offsets.code_offset_); method->SetOatNativeGcMapOffset(offsets.gc_map_offset_); @@ -601,10 +567,10 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { // Deduplicate code arrays. const OatMethodOffsets& method_offsets = oat_class->method_offsets_[method_offsets_index_]; DCHECK(method_offsets.code_offset_ < offset_ || method_offsets.code_offset_ == - offset_ + sizeof(OatMethodHeader) + compiled_method->CodeDelta()) + offset_ + sizeof(OatQuickMethodHeader) + compiled_method->CodeDelta()) << PrettyMethod(it.GetMemberIndex(), *dex_file_); if (method_offsets.code_offset_ >= offset_) { - const OatMethodHeader& method_header = oat_class->method_headers_[method_offsets_index_]; + const OatQuickMethodHeader& method_header = oat_class->method_headers_[method_offsets_index_]; if (!out->WriteFully(&method_header, sizeof(method_header))) { ReportWriteFailure("method header", it); return false; diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h index 7cdd5329bd..85c9b4761a 100644 --- a/compiler/oat_writer.h +++ b/compiler/oat_writer.h @@ -231,7 +231,7 @@ class OatWriter { // oat_method_offsets_offsets_from_oat_class_ should contain 0 // values in this case). std::vector<OatMethodOffsets> method_offsets_; - std::vector<OatMethodHeader> method_headers_; + std::vector<OatQuickMethodHeader> method_headers_; private: DISALLOW_COPY_AND_ASSIGN(OatClass); |