Changeset 161377 in webkit
- Timestamp:
- Jan 6, 2014 3:04:25 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r161365 r161377 1 2014-01-06 Mark Hahnenberg <mhahnenberg@apple.com> 2 3 Add write barriers to the LLInt 4 https://bugs.webkit.org/show_bug.cgi?id=126527 5 6 Reviewed by Filip Pizlo. 7 8 This patch takes a similar approach to how write barriers work in the baseline JIT. 9 We execute the write barrier at the beginning of the opcode so we don't have to 10 worry about saving and restoring live registers across write barrier slow path calls 11 to C code. 12 13 * llint/LLIntOfflineAsmConfig.h: 14 * llint/LLIntSlowPaths.cpp: 15 (JSC::LLInt::llint_write_barrier_slow): 16 * llint/LLIntSlowPaths.h: 17 * llint/LowLevelInterpreter.asm: 18 * llint/LowLevelInterpreter32_64.asm: 19 * llint/LowLevelInterpreter64.asm: 20 * offlineasm/arm64.rb: 21 * offlineasm/instructions.rb: 22 * offlineasm/x86.rb: 23 1 24 2014-01-05 Sam Weinig <sam@webkit.org> 2 25 -
trunk/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
r161364 r161377 149 149 #endif 150 150 151 #if ENABLE(GGC) 152 #define OFFLINE_ASM_GGC 1 153 #else 154 #define OFFLINE_ASM_GGC 0 155 #endif 156 151 157 #endif // LLIntOfflineAsmConfig_h -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r161364 r161377 1389 1389 } 1390 1390 1391 extern "C" void llint_write_barrier_slow(ExecState*, JSCell* cell) 1392 { 1393 Heap::writeBarrier(cell); 1394 } 1395 1391 1396 } } // namespace JSC::LLInt 1392 1397 -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h
r160244 r161377 42 42 extern "C" SlowPathReturnType llint_trace_operand(ExecState*, Instruction*, int fromWhere, int operand); 43 43 extern "C" SlowPathReturnType llint_trace_value(ExecState*, Instruction*, int fromWhere, int operand); 44 extern "C" void llint_write_barrier_slow(ExecState*, JSCell*); 44 45 45 46 #define LLINT_SLOW_PATH_DECL(name) \ -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r161364 r161377 171 171 const ResolveModeMask = 0xffff 172 172 173 const MarkedBlockMask = ~0xffff 173 const MarkedBlockSize = 64 * 1024 174 const MarkedBlockMask = ~(MarkedBlockSize - 1) 175 # Constants for checking mark bits. 176 const AtomNumberShift = 3 177 const BitMapWordShift = 4 174 178 175 179 # Allocation constants … … 262 266 storep structure, ArrayProfile::m_lastSeenStructure[profile] 263 267 loadb Structure::m_indexingType[structure], indexingType 268 end 269 270 macro checkMarkByte(cell, scratch1, scratch2, continuation) 271 move cell, scratch1 272 move cell, scratch2 273 274 andp MarkedBlockMask, scratch1 275 andp ~MarkedBlockMask, scratch2 276 277 rshiftp AtomNumberShift + BitMapWordShift, scratch2 278 loadb MarkedBlock::m_marks[scratch1, scratch2, 1], scratch1 279 continuation(scratch1) 264 280 end 265 281 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r161364 r161377 492 492 end 493 493 494 macro writeBarrier(tag, payload) 495 # Nothing to do, since we don't have a generational or incremental collector. 494 macro writeBarrierOnOperand(cellOperand) 495 if GGC 496 loadisFromInstruction(cellOperand, t1) 497 loadConstantOrVariablePayload(t1, CellTag, t0, .writeBarrierDone) 498 checkMarkByte(t0, t1, t2, 499 macro(marked) 500 btbz marked, .writeBarrierDone 501 push cfr, PC 502 # We make two extra slots because cCall2 will poke. 503 subp 8, sp 504 cCall2(_llint_write_barrier_slow, cfr, t0) 505 addp 8, sp 506 pop PC, cfr 507 end 508 ) 509 .writeBarrierDone: 510 end 511 end 512 513 macro writeBarrierOnOperands(cellOperand, valueOperand) 514 if GGC 515 loadisFromInstruction(valueOperand, t1) 516 loadConstantOrVariableTag(t1, t0) 517 bineq t0, CellTag, .writeBarrierDone 518 519 writeBarrierOnOperand(cellOperand) 520 .writeBarrierDone: 521 end 522 end 523 524 macro writeBarrierOnGlobalObject(valueOperand) 525 if GGC 526 loadisFromInstruction(valueOperand, t1) 527 bineq t0, CellTag, .writeBarrierDone 528 529 loadp CodeBlock[cfr], t0 530 loadp CodeBlock::m_globalObject[t0], t0 531 checkMarkByte(t0, t1, t2, 532 macro(marked) 533 btbz marked, .writeBarrierDone 534 push cfr, PC 535 # We make two extra slots because cCall2 will poke. 536 subp 8, sp 537 cCall2(_llint_write_barrier_slow, cfr, t0) 538 addp 8, sp 539 pop PC, cfr 540 end 541 ) 542 .writeBarrierDone: 543 end 496 544 end 497 545 … … 576 624 btinz t2, .opEnterLoop 577 625 .opEnterDone: 626 callSlowPath(_slow_path_enter) 578 627 dispatch(1) 579 628 … … 1256 1305 _llint_op_init_global_const: 1257 1306 traceExecution() 1307 writeBarrierOnGlobalObject(2) 1258 1308 loadi 8[PC], t1 1259 1309 loadi 4[PC], t0 1260 1310 loadConstantOrVariable(t1, t2, t3) 1261 writeBarrier(t2, t3)1262 1311 storei t2, TagOffset[t0] 1263 1312 storei t3, PayloadOffset[t0] … … 1345 1394 macro putById(getPropertyStorage) 1346 1395 traceExecution() 1396 writeBarrierOnOperands(1, 3) 1347 1397 loadi 4[PC], t3 1348 1398 loadi 16[PC], t1 … … 1356 1406 loadi 20[PC], t1 1357 1407 loadConstantOrVariable2Reg(t2, scratch, t2) 1358 writeBarrier(scratch, t2)1359 1408 storei scratch, TagOffset[propertyStorage, t1] 1360 1409 storei t2, PayloadOffset[propertyStorage, t1] … … 1377 1426 macro putByIdTransition(additionalChecks, getPropertyStorage) 1378 1427 traceExecution() 1428 writeBarrierOnOperand(1) 1379 1429 loadi 4[PC], t3 1380 1430 loadi 16[PC], t1 … … 1390 1440 addp t1, propertyStorage, t3 1391 1441 loadConstantOrVariable2Reg(t2, t1, t2) 1392 writeBarrier(t1, t2)1393 1442 storei t1, TagOffset[t3] 1394 1443 loadi 24[PC], t1 … … 1562 1611 macro putByVal(holeCheck, slowPath) 1563 1612 traceExecution() 1613 writeBarrierOnOperands(1, 3) 1564 1614 loadi 4[PC], t0 1565 1615 loadConstantOrVariablePayload(t0, CellTag, t1, .opPutByValSlow) … … 1603 1653 const payload = operand 1604 1654 loadConstantOrVariable2Reg(operand, tag, payload) 1605 writeBarrier(tag, payload)1606 1655 storei tag, TagOffset[base, index, 8] 1607 1656 storei payload, PayloadOffset[base, index, 8] … … 1615 1664 loadi 12[PC], t2 1616 1665 loadConstantOrVariable2Reg(t2, t1, t2) 1617 writeBarrier(t1, t2)1618 1666 storei t1, ArrayStorage::m_vector + TagOffset[t0, t3, 8] 1619 1667 storei t2, ArrayStorage::m_vector + PayloadOffset[t0, t3, 8] … … 2340 2388 #pGlobalProperty: 2341 2389 bineq t0, GlobalProperty, .pGlobalVar 2390 writeBarrierOnOperands(1, 3) 2342 2391 loadWithStructureCheck(1, .pDynamic) 2343 2392 putProperty() … … 2346 2395 .pGlobalVar: 2347 2396 bineq t0, GlobalVar, .pClosureVar 2397 writeBarrierOnGlobalObject(3) 2348 2398 putGlobalVar() 2349 2399 dispatch(7) … … 2351 2401 .pClosureVar: 2352 2402 bineq t0, ClosureVar, .pGlobalPropertyWithVarInjectionChecks 2403 writeBarrierOnOperands(1, 3) 2353 2404 loadVariable(1, t2, t1, t0) 2354 2405 putClosureVar() … … 2357 2408 .pGlobalPropertyWithVarInjectionChecks: 2358 2409 bineq t0, GlobalPropertyWithVarInjectionChecks, .pGlobalVarWithVarInjectionChecks 2410 writeBarrierOnOperands(1, 3) 2359 2411 loadWithStructureCheck(1, .pDynamic) 2360 2412 putProperty() … … 2363 2415 .pGlobalVarWithVarInjectionChecks: 2364 2416 bineq t0, GlobalVarWithVarInjectionChecks, .pClosureVarWithVarInjectionChecks 2417 writeBarrierOnGlobalObject(3) 2365 2418 varInjectionCheck(.pDynamic) 2366 2419 putGlobalVar() … … 2369 2422 .pClosureVarWithVarInjectionChecks: 2370 2423 bineq t0, ClosureVarWithVarInjectionChecks, .pDynamic 2424 writeBarrierOnOperands(1, 3) 2371 2425 varInjectionCheck(.pDynamic) 2372 2426 loadVariable(1, t2, t1, t0) -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r161364 r161377 332 332 end 333 333 334 macro writeBarrier(value) 335 # Nothing to do, since we don't have a generational or incremental collector. 334 macro writeBarrierOnOperand(cellOperand) 335 if GGC 336 loadisFromInstruction(cellOperand, t1) 337 loadConstantOrVariableCell(t1, t0, .writeBarrierDone) 338 checkMarkByte(t0, t1, t2, 339 macro(marked) 340 btbz marked, .writeBarrierDone 341 push PB, PC 342 cCall2(_llint_write_barrier_slow, cfr, t0) 343 push PC, PB 344 end 345 ) 346 .writeBarrierDone: 347 end 348 end 349 350 macro writeBarrierOnOperands(cellOperand, valueOperand) 351 if GGC 352 loadisFromInstruction(valueOperand, t1) 353 loadConstantOrVariable(t1, t0) 354 btpz t0, .writeBarrierDone 355 356 writeBarrierOnOperand(cellOperand) 357 .writeBarrierDone: 358 end 359 end 360 361 macro writeBarrierOnGlobalObject(valueOperand) 362 if GGC 363 loadisFromInstruction(valueOperand, t1) 364 loadConstantOrVariable(t1, t0) 365 btpz t0, .writeBarrierDone 366 367 loadp CodeBlock[cfr], t0 368 loadp CodeBlock::m_globalObject[t0], t0 369 checkMarkByte(t0, t1, t2, 370 macro(marked) 371 btbz marked, .writeBarrierDone 372 push PB, PC 373 cCall2(_llint_write_barrier_slow, cfr, t0) 374 pop PC, PB 375 end 376 ) 377 .writeBarrierDone: 378 end 336 379 end 337 380 … … 413 456 btqnz t2, .opEnterLoop 414 457 .opEnterDone: 458 callSlowPath(_slow_path_enter) 415 459 dispatch(1) 416 460 … … 1065 1109 _llint_op_init_global_const: 1066 1110 traceExecution() 1111 writeBarrierOnGlobalObject(2) 1067 1112 loadisFromInstruction(2, t1) 1068 1113 loadpFromInstruction(1, t0) 1069 1114 loadConstantOrVariable(t1, t2) 1070 writeBarrier(t2)1071 1115 storeq t2, [t0] 1072 1116 dispatch(5) … … 1150 1194 macro putById(getPropertyStorage) 1151 1195 traceExecution() 1196 writeBarrierOnOperands(1, 3) 1152 1197 loadisFromInstruction(1, t3) 1153 1198 loadpFromInstruction(4, t1) … … 1161 1206 loadisFromInstruction(5, t1) 1162 1207 loadConstantOrVariable(t2, scratch) 1163 writeBarrier(t0)1164 1208 storeq scratch, [propertyStorage, t1] 1165 1209 dispatch(9) … … 1181 1225 macro putByIdTransition(additionalChecks, getPropertyStorage) 1182 1226 traceExecution() 1227 writeBarrierOnOperand(1) 1183 1228 loadisFromInstruction(1, t3) 1184 1229 loadpFromInstruction(4, t1) … … 1194 1239 addp t1, propertyStorage, t3 1195 1240 loadConstantOrVariable(t2, t1) 1196 writeBarrier(t1)1197 1241 storeq t1, [t3] 1198 1242 loadpFromInstruction(6, t1) … … 1363 1407 macro putByVal(holeCheck, slowPath) 1364 1408 traceExecution() 1409 writeBarrierOnOperands(1, 3) 1365 1410 loadisFromInstruction(1, t0) 1366 1411 loadConstantOrVariableCell(t0, t1, .opPutByValSlow) … … 1402 1447 macro (operand, scratch, address) 1403 1448 loadConstantOrVariable(operand, scratch) 1404 writeBarrier(scratch)1405 1449 storep scratch, address 1406 1450 end) … … 1413 1457 loadisFromInstruction(3, t2) 1414 1458 loadConstantOrVariable(t2, t1) 1415 writeBarrier(t1)1416 1459 storeq t1, ArrayStorage::m_vector[t0, t3, 8] 1417 1460 dispatch(5) … … 2108 2151 #pGlobalProperty: 2109 2152 bineq t0, GlobalProperty, .pGlobalVar 2153 writeBarrierOnOperands(1, 3) 2110 2154 loadWithStructureCheck(1, .pDynamic) 2111 2155 putProperty() … … 2114 2158 .pGlobalVar: 2115 2159 bineq t0, GlobalVar, .pClosureVar 2160 writeBarrierOnGlobalObject(3) 2116 2161 putGlobalVar() 2117 2162 dispatch(7) … … 2119 2164 .pClosureVar: 2120 2165 bineq t0, ClosureVar, .pGlobalPropertyWithVarInjectionChecks 2166 writeBarrierOnOperands(1, 3) 2121 2167 loadVariable(1, t0) 2122 2168 putClosureVar() … … 2125 2171 .pGlobalPropertyWithVarInjectionChecks: 2126 2172 bineq t0, GlobalPropertyWithVarInjectionChecks, .pGlobalVarWithVarInjectionChecks 2173 writeBarrierOnOperands(1, 3) 2127 2174 loadWithStructureCheck(1, .pDynamic) 2128 2175 putProperty() … … 2131 2178 .pGlobalVarWithVarInjectionChecks: 2132 2179 bineq t0, GlobalVarWithVarInjectionChecks, .pClosureVarWithVarInjectionChecks 2180 writeBarrierOnGlobalObject(3) 2133 2181 varInjectionCheck(.pDynamic) 2134 2182 putGlobalVar() … … 2137 2185 .pClosureVarWithVarInjectionChecks: 2138 2186 bineq t0, ClosureVarWithVarInjectionChecks, .pDynamic 2187 writeBarrierOnOperands(1, 3) 2139 2188 varInjectionCheck(.pDynamic) 2140 2189 loadVariable(1, t0) -
trunk/Source/JavaScriptCore/offlineasm/arm.rb
r159545 r161377 458 458 raise "ARM does not support this opcode yet, #{codeOrigin}" 459 459 when "pop" 460 $asm.puts "pop { #{operands[0].armOperand} }" 460 operands.each { 461 | op | 462 $asm.puts "pop { #{op.armOperand} }" 463 } 461 464 when "push" 462 $asm.puts "push { #{operands[0].armOperand} }" 465 operands.each { 466 | op | 467 $asm.puts "push { #{op.armOperand} }" 468 } 463 469 when "popCalleeSaves" 464 470 if isARMv7 -
trunk/Source/JavaScriptCore/offlineasm/arm64.rb
r159655 r161377 567 567 raise "ARM64 does not support this opcode yet, #{codeOriginString}" 568 568 when "pop" 569 # FIXME: Remove it or support it. 570 raise "ARM64 does not support this opcode yet, #{codeOriginString}" 569 operands.each_slice(2) { 570 | ops | 571 # Note that the operands are in the reverse order of the case for push. 572 # This is due to the fact that order matters for pushing and popping, and 573 # on platforms that only push/pop one slot at a time they pop their 574 # arguments in the reverse order that they were pushed. In order to remain 575 # compatible with those platforms we assume here that that's what has been done. 576 577 # So for example, if we did push(A, B, C, D), we would then pop(D, C, B, A). 578 # But since the ordering of arguments doesn't change on arm64 between the stp and ldp 579 # instructions we need to flip flop the argument positions that were passed to us. 580 $asm.puts "ldp #{ops[1].arm64Operand(:ptr)}, #{ops[0].arm64Operand(:ptr)}, [sp], #16" 581 } 571 582 when "push" 572 # FIXME: Remove it or support it. 573 raise "ARM64 does not support this opcode yet, #{codeOriginString}" 583 operands.each_slice(2) { 584 | ops | 585 $asm.puts "stp #{ops[0].arm64Operand(:ptr)}, #{ops[1].arm64Operand(:ptr)}, [sp, #-16]!" 586 } 574 587 when "popLRAndFP" 575 588 $asm.puts "ldp fp, lr, [sp], #16" -
trunk/Source/JavaScriptCore/offlineasm/mips.rb
r160387 r161377 840 840 raise "MIPS does not support this opcode yet, #{codeOrigin}" 841 841 when "pop" 842 $asm.puts "lw #{operands[0].mipsOperand}, 0($sp)" 843 $asm.puts "addiu $sp, $sp, 4" 842 operands.each { 843 | op | 844 $asm.puts "lw #{op.mipsOperand}, 0($sp)" 845 $asm.puts "addiu $sp, $sp, 4" 846 } 844 847 when "push" 845 $asm.puts "addiu $sp, $sp, -4" 846 $asm.puts "sw #{operands[0].mipsOperand}, 0($sp)" 848 operands.each { 849 | op | 850 $asm.puts "addiu $sp, $sp, -4" 851 $asm.puts "sw #{op.mipsOperand}, 0($sp)" 852 } 847 853 when "popCalleeSaves" 848 854 $asm.puts "lw $16, 0($sp)" -
trunk/Source/JavaScriptCore/offlineasm/x86.rb
r159654 r161377 101 101 isX64 ? "%rax" : raise 102 102 else 103 raise 103 raise "Invalid kind #{kind} for name #{name}" 104 104 end 105 105 when "t1", "a1", "r1" … … 979 979 end 980 980 when "pop" 981 $asm.puts "pop #{operands[0].x86Operand(:ptr)}" 981 operands.each { 982 | op | 983 $asm.puts "pop #{op.x86Operand(:ptr)}" 984 } 982 985 when "push" 983 $asm.puts "push #{operands[0].x86Operand(:ptr)}" 986 operands.each { 987 | op | 988 $asm.puts "push #{op.x86Operand(:ptr)}" 989 } 984 990 when "popCalleeSaves" 985 991 if isX64
Note: See TracChangeset
for help on using the changeset viewer.