Changeset 180279 in webkit for trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp
- Timestamp:
- Feb 18, 2015, 11:55:47 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp
r177597 r180279 1 1 /* 2 * Copyright (C) 2013 , 2014Apple Inc. All rights reserved.2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2014 Samsung Electronics 4 4 * Copyright (C) 2014 University of Szeged … … 129 129 } 130 130 131 static int offsetOfStackRegion(StackMaps::RecordMap& recordMap, uint32_t stackmapID) 132 { 133 StackMaps::RecordMap::iterator iter = recordMap.find(stackmapID); 134 RELEASE_ASSERT(iter != recordMap.end()); 135 RELEASE_ASSERT(iter->value.size() == 1); 136 RELEASE_ASSERT(iter->value[0].locations.size() == 1); 137 Location capturedLocation = 138 Location::forStackmaps(nullptr, iter->value[0].locations[0]); 139 RELEASE_ASSERT(capturedLocation.kind() == Location::Register); 140 RELEASE_ASSERT(capturedLocation.gpr() == GPRInfo::callFrameRegister); 141 RELEASE_ASSERT(!(capturedLocation.addend() % sizeof(Register))); 142 return capturedLocation.addend() / sizeof(Register); 143 } 144 131 145 template<typename DescriptorType> 132 146 void generateICFastPath( … … 244 258 } 245 259 260 template<typename CallType> 261 void adjustCallICsForStackmaps(Vector<CallType>& calls, StackMaps::RecordMap& recordMap) 262 { 263 // Handling JS calls is weird: we need to ensure that we sort them by the PC in LLVM 264 // generated code. That implies first pruning the ones that LLVM didn't generate. 265 266 Vector<CallType> oldCalls; 267 oldCalls.swap(calls); 268 269 for (unsigned i = 0; i < oldCalls.size(); ++i) { 270 CallType& call = oldCalls[i]; 271 272 StackMaps::RecordMap::iterator iter = recordMap.find(call.stackmapID()); 273 if (iter == recordMap.end()) 274 continue; 275 276 for (unsigned j = 0; j < iter->value.size(); ++j) { 277 CallType copy = call; 278 copy.m_instructionOffset = iter->value[j].instructionOffset; 279 calls.append(copy); 280 } 281 } 282 283 std::sort(calls.begin(), calls.end()); 284 } 285 246 286 static void fixFunctionBasedOnStackMaps( 247 287 State& state, CodeBlock* codeBlock, JITCode* jitCode, GeneratedFunction generatedFunction, … … 252 292 StackMaps stackmaps = jitCode->stackmaps; 253 293 254 StackMaps::RecordMap::iterator iter = recordMap.find(state.capturedStackmapID); 255 RELEASE_ASSERT(iter != recordMap.end()); 256 RELEASE_ASSERT(iter->value.size() == 1); 257 RELEASE_ASSERT(iter->value[0].locations.size() == 1); 258 Location capturedLocation = 259 Location::forStackmaps(&jitCode->stackmaps, iter->value[0].locations[0]); 260 RELEASE_ASSERT(capturedLocation.kind() == Location::Register); 261 RELEASE_ASSERT(capturedLocation.gpr() == GPRInfo::callFrameRegister); 262 RELEASE_ASSERT(!(capturedLocation.addend() % sizeof(Register))); 263 int32_t localsOffset = capturedLocation.addend() / sizeof(Register) + graph.m_nextMachineLocal; 294 int localsOffset = 295 offsetOfStackRegion(recordMap, state.capturedStackmapID) + graph.m_nextMachineLocal; 296 297 int varargsSpillSlotsOffset; 298 if (state.varargsSpillSlotsStackmapID != UINT_MAX) 299 varargsSpillSlotsOffset = offsetOfStackRegion(recordMap, state.varargsSpillSlotsStackmapID); 300 else 301 varargsSpillSlotsOffset = 0; 264 302 265 303 for (unsigned i = graph.m_inlineVariableData.size(); i--;) { … … 294 332 // At this point it's perfectly fair to just blow away all state and restore the 295 333 // JS JIT view of the universe. 296 checkJIT.move(MacroAssembler::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister);297 checkJIT.move(MacroAssembler::TrustedImm64(TagMask), GPRInfo::tagMaskRegister);298 299 334 checkJIT.move(MacroAssembler::TrustedImmPtr(&vm), GPRInfo::argumentGPR0); 300 335 checkJIT.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1); … … 303 338 304 339 stackOverflowException = checkJIT.label(); 305 checkJIT.move(MacroAssembler::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister);306 checkJIT.move(MacroAssembler::TrustedImm64(TagMask), GPRInfo::tagMaskRegister);307 308 340 checkJIT.move(MacroAssembler::TrustedImmPtr(&vm), GPRInfo::argumentGPR0); 309 341 checkJIT.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1); … … 337 369 dataLog("Handling OSR stackmap #", exit.m_stackmapID, " for ", exit.m_codeOrigin, "\n"); 338 370 339 iter = recordMap.find(exit.m_stackmapID);371 auto iter = recordMap.find(exit.m_stackmapID); 340 372 if (iter == recordMap.end()) { 341 373 // It was optimized out. … … 376 408 dataLog("Handling GetById stackmap #", getById.stackmapID(), "\n"); 377 409 378 iter = recordMap.find(getById.stackmapID());410 auto iter = recordMap.find(getById.stackmapID()); 379 411 if (iter == recordMap.end()) { 380 412 // It was optimized out. … … 413 445 dataLog("Handling PutById stackmap #", putById.stackmapID(), "\n"); 414 446 415 iter = recordMap.find(putById.stackmapID());447 auto iter = recordMap.find(putById.stackmapID()); 416 448 if (iter == recordMap.end()) { 417 449 // It was optimized out. … … 445 477 } 446 478 447 448 479 for (unsigned i = state.checkIns.size(); i--;) { 449 480 CheckInDescriptor& checkIn = state.checkIns[i]; … … 452 483 dataLog("Handling checkIn stackmap #", checkIn.stackmapID(), "\n"); 453 484 454 iter = recordMap.find(checkIn.stackmapID());485 auto iter = recordMap.find(checkIn.stackmapID()); 455 486 if (iter == recordMap.end()) { 456 487 // It was optimized out. … … 481 512 } 482 513 } 483 484 514 485 515 exceptionTarget.link(&slowPathJIT); … … 504 534 generateCheckInICFastPath( 505 535 state, codeBlock, generatedFunction, recordMap, state.checkIns[i], 506 sizeOf CheckIn());536 sizeOfIn()); 507 537 } 508 538 } 509 539 510 // Handling JS calls is weird: we need to ensure that we sort them by the PC in LLVM 511 // generated code. That implies first pruning the ones that LLVM didn't generate. 512 Vector<JSCall> oldCalls = state.jsCalls; 513 state.jsCalls.resize(0); 514 for (unsigned i = 0; i < oldCalls.size(); ++i) { 515 JSCall& call = oldCalls[i]; 516 517 StackMaps::RecordMap::iterator iter = recordMap.find(call.stackmapID()); 518 if (iter == recordMap.end()) 519 continue; 520 521 for (unsigned j = 0; j < iter->value.size(); ++j) { 522 JSCall copy = call; 523 copy.m_instructionOffset = iter->value[j].instructionOffset; 524 state.jsCalls.append(copy); 525 } 526 } 527 528 std::sort(state.jsCalls.begin(), state.jsCalls.end()); 540 adjustCallICsForStackmaps(state.jsCalls, recordMap); 529 541 530 542 for (unsigned i = state.jsCalls.size(); i--;) { … … 548 560 } 549 561 562 adjustCallICsForStackmaps(state.jsCallVarargses, recordMap); 563 564 for (unsigned i = state.jsCallVarargses.size(); i--;) { 565 JSCallVarargs& call = state.jsCallVarargses[i]; 566 567 CCallHelpers fastPathJIT(&vm, codeBlock); 568 call.emit(fastPathJIT, graph, varargsSpillSlotsOffset); 569 570 char* startOfIC = bitwise_cast<char*>(generatedFunction) + call.m_instructionOffset; 571 size_t sizeOfIC = sizeOfICFor(call.node()); 572 573 LinkBuffer linkBuffer(vm, fastPathJIT, startOfIC, sizeOfIC); 574 if (!linkBuffer.isValid()) { 575 dataLog("Failed to insert inline cache for varargs call (specifically, ", Graph::opName(call.node()->op()), ") because we thought the size would be ", sizeOfIC, " but it ended up being ", fastPathJIT.m_assembler.codeSize(), " prior to compaction.\n"); 576 RELEASE_ASSERT_NOT_REACHED(); 577 } 578 579 MacroAssembler::AssemblerType_T::fillNops( 580 startOfIC + linkBuffer.size(), sizeOfIC - linkBuffer.size()); 581 582 call.link(vm, linkBuffer, state.finalizer->handleExceptionsLinkBuffer->entrypoint()); 583 } 584 550 585 RepatchBuffer repatchBuffer(codeBlock); 551 586 552 iter = recordMap.find(state.handleStackOverflowExceptionStackmapID);587 auto iter = recordMap.find(state.handleStackOverflowExceptionStackmapID); 553 588 // It's sort of remotely possible that we won't have an in-band exception handling 554 589 // path, for some kinds of functions.
Note:
See TracChangeset
for help on using the changeset viewer.