Test the basic function of a codegen cache.
| 261 | |
| 262 | /// Test the basic function of a codegen cache. |
| 263 | void LlvmCodeGenCacheTest::TestBasicFunction(TCodeGenCacheMode::type mode) { |
| 264 | bool is_normal_mode = !CodeGenCacheModeAnalyzer::is_optimal(mode); |
| 265 | |
| 266 | // Create a LlvmCodeGen containing a codegen function Echo. |
| 267 | scoped_ptr<LlvmCodeGen> codegen_echo; |
| 268 | ASSERT_OK( |
| 269 | LlvmCodeGen::CreateImpalaCodegen(fragment_state_, nullptr, "test", &codegen_echo)); |
| 270 | string module_id_echo; |
| 271 | codegen_echo->engine_cache_ = CreateObjCache(false /*is_double*/, &module_id_echo); |
| 272 | // Create a LlvmCodeGen containing a codegen function Double. |
| 273 | scoped_ptr<LlvmCodeGen> codegen_double; |
| 274 | ASSERT_OK(LlvmCodeGen::CreateImpalaCodegen( |
| 275 | fragment_state_, nullptr, "test_double", &codegen_double)); |
| 276 | string module_id_double; |
| 277 | codegen_double->engine_cache_ = CreateObjCache(true /*is_double*/, &module_id_double); |
| 278 | CheckObjCacheExists(codegen_echo.get()); |
| 279 | CheckObjCacheExists(codegen_double.get()); |
| 280 | |
| 281 | CodeGenCacheKey cache_key; |
| 282 | CodeGenCacheEntry entry; |
| 283 | string key = "key"; |
| 284 | CodeGenCacheKeyConstructor::construct(key, &cache_key); |
| 285 | int64_t mem_charge_echo = |
| 286 | GetMemCharge(codegen_echo.get(), cache_key.data(), is_normal_mode); |
| 287 | int64_t mem_charge_double = |
| 288 | GetMemCharge(codegen_double.get(), cache_key.data(), is_normal_mode); |
| 289 | |
| 290 | scoped_ptr<MetricGroup> metrics; |
| 291 | metrics.reset(new MetricGroup("codegen-cache-test-basic")); |
| 292 | codegen_cache_.reset(new CodeGenCache(metrics.get())); |
| 293 | EXPECT_OK(codegen_cache_->Init(CODEGEN_CACHE_CAPACITY)); |
| 294 | // Store and lookup the entry by the key. |
| 295 | EXPECT_OK(codegen_cache_->Store(cache_key, codegen_echo.get(), mode, opt_level_)); |
| 296 | CheckInUseMetrics( |
| 297 | codegen_cache_.get(), 1 /*num_entry_in_use*/, mem_charge_echo /*bytes_in_use*/); |
| 298 | EXPECT_OK(codegen_cache_->Lookup(cache_key, mode, &entry, &codegen_obj_cache_)); |
| 299 | CheckResult(entry, module_id_echo); |
| 300 | codegen_echo->Close(); |
| 301 | // Close the LlvmCodeGen, but should not affect the stored cache. |
| 302 | EXPECT_OK(codegen_cache_->Lookup(cache_key, mode, &entry, &codegen_obj_cache_)); |
| 303 | CheckResult(entry, module_id_echo); |
| 304 | // Override the entry with a different function, should be able to find the new |
| 305 | // function from the new entry. |
| 306 | EXPECT_OK(codegen_cache_->Store(cache_key, codegen_double.get(), mode, opt_level_)); |
| 307 | CheckInUseMetrics( |
| 308 | codegen_cache_.get(), 1 /*num_entry_in_use*/, mem_charge_double /*bytes_in_use*/); |
| 309 | EXPECT_OK(codegen_cache_->Lookup(cache_key, mode, &entry, &codegen_obj_cache_)); |
| 310 | CheckResult(entry, module_id_double, true /*is_double*/); |
| 311 | EXPECT_EQ(codegen_cache_->codegen_cache_entries_evicted_->GetValue(), 1); |
| 312 | codegen_double->Close(); |
| 313 | codegen_cache_.reset(); |
| 314 | } |
| 315 | |
| 316 | void LlvmCodeGenCacheTest::CheckMetrics( |
| 317 | CodeGenCache* codegen_cache, int hit, int miss, int evict) { |