| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> | 3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * | 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 | 340 |
| 341 JSValuePtr result = jsUndefined(); | 341 JSValuePtr result = jsUndefined(); |
| 342 if (evalNode) | 342 if (evalNode) |
| 343 result = callFrame->globalData().interpreter->execute(evalNode.get(), ca
llFrame, callFrame->thisValue().toThisObject(callFrame), callFrame->registers()
- registerFile->start() + registerOffset, scopeChain, &exceptionValue); | 343 result = callFrame->globalData().interpreter->execute(evalNode.get(), ca
llFrame, callFrame->thisValue().toThisObject(callFrame), callFrame->registers()
- registerFile->start() + registerOffset, scopeChain, &exceptionValue); |
| 344 | 344 |
| 345 return result; | 345 return result; |
| 346 } | 346 } |
| 347 | 347 |
| 348 Interpreter::Interpreter() | 348 Interpreter::Interpreter() |
| 349 : m_sampler(0) | 349 : m_sampler(0) |
| 350 #if ENABLE(JIT) | |
| 351 , m_ctiArrayLengthTrampoline(0) | |
| 352 , m_ctiStringLengthTrampoline(0) | |
| 353 , m_ctiVirtualCallPreLink(0) | |
| 354 , m_ctiVirtualCallLink(0) | |
| 355 , m_ctiVirtualCall(0) | |
| 356 #endif | |
| 357 , m_reentryDepth(0) | 350 , m_reentryDepth(0) |
| 358 { | 351 { |
| 359 privateExecute(InitializeAndReturn, 0, 0, 0); | 352 privateExecute(InitializeAndReturn, 0, 0, 0); |
| 360 | |
| 361 // Bizarrely, calling fastMalloc here is faster than allocating space on the
stack. | |
| 362 void* storage = fastMalloc(sizeof(CollectorBlock)); | |
| 363 | |
| 364 JSCell* jsArray = new (storage) JSArray(JSArray::createStructure(jsNull())); | |
| 365 m_jsArrayVptr = jsArray->vptr(); | |
| 366 jsArray->~JSCell(); | |
| 367 | |
| 368 JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHac
k); | |
| 369 m_jsByteArrayVptr = jsByteArray->vptr(); | |
| 370 jsByteArray->~JSCell(); | |
| 371 | |
| 372 JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack); | |
| 373 m_jsStringVptr = jsString->vptr(); | |
| 374 jsString->~JSCell(); | |
| 375 | |
| 376 JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(js
Null())); | |
| 377 m_jsFunctionVptr = jsFunction->vptr(); | |
| 378 jsFunction->~JSCell(); | |
| 379 | |
| 380 fastFree(storage); | |
| 381 } | |
| 382 | |
| 383 void Interpreter::initialize(JSGlobalData* globalData) | |
| 384 { | |
| 385 #if ENABLE(JIT) | |
| 386 JIT::compileCTIMachineTrampolines(globalData); | |
| 387 #else | |
| 388 UNUSED_PARAM(globalData); | |
| 389 #endif | |
| 390 } | |
| 391 | |
| 392 Interpreter::~Interpreter() | |
| 393 { | |
| 394 } | 353 } |
| 395 | 354 |
| 396 #ifndef NDEBUG | 355 #ifndef NDEBUG |
| 397 | 356 |
| 398 void Interpreter::dumpCallFrame(CallFrame* callFrame) | 357 void Interpreter::dumpCallFrame(CallFrame* callFrame) |
| 399 { | 358 { |
| 400 callFrame->codeBlock()->dump(callFrame); | 359 callFrame->codeBlock()->dump(callFrame); |
| 401 dumpRegisters(callFrame); | 360 dumpRegisters(callFrame); |
| 402 } | 361 } |
| 403 | 362 |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 // Recursive invocation may already have specialized this instruction. | 914 // Recursive invocation may already have specialized this instruction. |
| 956 if (vPC[0].u.opcode != getOpcode(op_get_by_id)) | 915 if (vPC[0].u.opcode != getOpcode(op_get_by_id)) |
| 957 return; | 916 return; |
| 958 | 917 |
| 959 // FIXME: Cache property access for immediates. | 918 // FIXME: Cache property access for immediates. |
| 960 if (!baseValue.isCell()) { | 919 if (!baseValue.isCell()) { |
| 961 vPC[0] = getOpcode(op_get_by_id_generic); | 920 vPC[0] = getOpcode(op_get_by_id_generic); |
| 962 return; | 921 return; |
| 963 } | 922 } |
| 964 | 923 |
| 965 if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().lengt
h) { | 924 JSGlobalData* globalData = &callFrame->globalData(); |
| 925 if (isJSArray(globalData, baseValue) && propertyName == callFrame->propertyN
ames().length) { |
| 966 vPC[0] = getOpcode(op_get_array_length); | 926 vPC[0] = getOpcode(op_get_array_length); |
| 967 return; | 927 return; |
| 968 } | 928 } |
| 969 | 929 |
| 970 if (isJSString(baseValue) && propertyName == callFrame->propertyNames().leng
th) { | 930 if (isJSString(globalData, baseValue) && propertyName == callFrame->property
Names().length) { |
| 971 vPC[0] = getOpcode(op_get_string_length); | 931 vPC[0] = getOpcode(op_get_string_length); |
| 972 return; | 932 return; |
| 973 } | 933 } |
| 974 | 934 |
| 975 // Uncacheable: give up. | 935 // Uncacheable: give up. |
| 976 if (!slot.isCacheable()) { | 936 if (!slot.isCacheable()) { |
| 977 vPC[0] = getOpcode(op_get_by_id_generic); | 937 vPC[0] = getOpcode(op_get_by_id_generic); |
| 978 return; | 938 return; |
| 979 } | 939 } |
| 980 | 940 |
| (...skipping 1285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2266 DEFINE_OPCODE(op_get_array_length) { | 2226 DEFINE_OPCODE(op_get_array_length) { |
| 2267 /* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n
) nop(n) | 2227 /* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n
) nop(n) |
| 2268 | 2228 |
| 2269 Cached property access: Gets the length of the array in register base
, | 2229 Cached property access: Gets the length of the array in register base
, |
| 2270 and puts the result in register dst. If register base does not hold | 2230 and puts the result in register dst. If register base does not hold |
| 2271 an array, op_get_array_length reverts to op_get_by_id. | 2231 an array, op_get_array_length reverts to op_get_by_id. |
| 2272 */ | 2232 */ |
| 2273 | 2233 |
| 2274 int base = vPC[2].u.operand; | 2234 int base = vPC[2].u.operand; |
| 2275 JSValuePtr baseValue = callFrame[base].jsValue(callFrame); | 2235 JSValuePtr baseValue = callFrame[base].jsValue(callFrame); |
| 2276 if (LIKELY(isJSArray(baseValue))) { | 2236 if (LIKELY(isJSArray(globalData, baseValue))) { |
| 2277 int dst = vPC[1].u.operand; | 2237 int dst = vPC[1].u.operand; |
| 2278 callFrame[dst] = JSValuePtr(jsNumber(callFrame, asArray(baseValue)->
length())); | 2238 callFrame[dst] = JSValuePtr(jsNumber(callFrame, asArray(baseValue)->
length())); |
| 2279 vPC += 8; | 2239 vPC += 8; |
| 2280 NEXT_INSTRUCTION(); | 2240 NEXT_INSTRUCTION(); |
| 2281 } | 2241 } |
| 2282 | 2242 |
| 2283 uncacheGetByID(callFrame->codeBlock(), vPC); | 2243 uncacheGetByID(callFrame->codeBlock(), vPC); |
| 2284 NEXT_INSTRUCTION(); | 2244 NEXT_INSTRUCTION(); |
| 2285 } | 2245 } |
| 2286 DEFINE_OPCODE(op_get_string_length) { | 2246 DEFINE_OPCODE(op_get_string_length) { |
| 2287 /* op_get_string_length dst(r) base(r) property(id) nop(sID) nop(n) nop(
n) nop(n) | 2247 /* op_get_string_length dst(r) base(r) property(id) nop(sID) nop(n) nop(
n) nop(n) |
| 2288 | 2248 |
| 2289 Cached property access: Gets the length of the string in register bas
e, | 2249 Cached property access: Gets the length of the string in register bas
e, |
| 2290 and puts the result in register dst. If register base does not hold | 2250 and puts the result in register dst. If register base does not hold |
| 2291 a string, op_get_string_length reverts to op_get_by_id. | 2251 a string, op_get_string_length reverts to op_get_by_id. |
| 2292 */ | 2252 */ |
| 2293 | 2253 |
| 2294 int base = vPC[2].u.operand; | 2254 int base = vPC[2].u.operand; |
| 2295 JSValuePtr baseValue = callFrame[base].jsValue(callFrame); | 2255 JSValuePtr baseValue = callFrame[base].jsValue(callFrame); |
| 2296 if (LIKELY(isJSString(baseValue))) { | 2256 if (LIKELY(isJSString(globalData, baseValue))) { |
| 2297 int dst = vPC[1].u.operand; | 2257 int dst = vPC[1].u.operand; |
| 2298 callFrame[dst] = JSValuePtr(jsNumber(callFrame, asString(baseValue)-
>value().size())); | 2258 callFrame[dst] = JSValuePtr(jsNumber(callFrame, asString(baseValue)-
>value().size())); |
| 2299 vPC += 8; | 2259 vPC += 8; |
| 2300 NEXT_INSTRUCTION(); | 2260 NEXT_INSTRUCTION(); |
| 2301 } | 2261 } |
| 2302 | 2262 |
| 2303 uncacheGetByID(callFrame->codeBlock(), vPC); | 2263 uncacheGetByID(callFrame->codeBlock(), vPC); |
| 2304 NEXT_INSTRUCTION(); | 2264 NEXT_INSTRUCTION(); |
| 2305 } | 2265 } |
| 2306 DEFINE_OPCODE(op_put_by_id) { | 2266 DEFINE_OPCODE(op_put_by_id) { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2468 int base = (++vPC)->u.operand; | 2428 int base = (++vPC)->u.operand; |
| 2469 int property = (++vPC)->u.operand; | 2429 int property = (++vPC)->u.operand; |
| 2470 | 2430 |
| 2471 JSValuePtr baseValue = callFrame[base].jsValue(callFrame); | 2431 JSValuePtr baseValue = callFrame[base].jsValue(callFrame); |
| 2472 JSValuePtr subscript = callFrame[property].jsValue(callFrame); | 2432 JSValuePtr subscript = callFrame[property].jsValue(callFrame); |
| 2473 | 2433 |
| 2474 JSValuePtr result; | 2434 JSValuePtr result; |
| 2475 | 2435 |
| 2476 if (LIKELY(subscript.isUInt32Fast())) { | 2436 if (LIKELY(subscript.isUInt32Fast())) { |
| 2477 uint32_t i = subscript.getUInt32Fast(); | 2437 uint32_t i = subscript.getUInt32Fast(); |
| 2478 if (isJSArray(baseValue)) { | 2438 if (isJSArray(globalData, baseValue)) { |
| 2479 JSArray* jsArray = asArray(baseValue); | 2439 JSArray* jsArray = asArray(baseValue); |
| 2480 if (jsArray->canGetIndex(i)) | 2440 if (jsArray->canGetIndex(i)) |
| 2481 result = jsArray->getIndex(i); | 2441 result = jsArray->getIndex(i); |
| 2482 else | 2442 else |
| 2483 result = jsArray->JSArray::get(callFrame, i); | 2443 result = jsArray->JSArray::get(callFrame, i); |
| 2484 } else if (isJSString(baseValue) && asString(baseValue)->canGetIndex
(i)) | 2444 } else if (isJSString(globalData, baseValue) && asString(baseValue)-
>canGetIndex(i)) |
| 2485 result = asString(baseValue)->getIndex(&callFrame->globalData(),
i); | 2445 result = asString(baseValue)->getIndex(&callFrame->globalData(),
i); |
| 2486 else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAcce
ssIndex(i)) | 2446 else if (isJSByteArray(globalData, baseValue) && asByteArray(baseVal
ue)->canAccessIndex(i)) |
| 2487 result = asByteArray(baseValue)->getIndex(callFrame, i); | 2447 result = asByteArray(baseValue)->getIndex(callFrame, i); |
| 2488 else | 2448 else |
| 2489 result = baseValue.get(callFrame, i); | 2449 result = baseValue.get(callFrame, i); |
| 2490 } else { | 2450 } else { |
| 2491 Identifier property(callFrame, subscript.toString(callFrame)); | 2451 Identifier property(callFrame, subscript.toString(callFrame)); |
| 2492 result = baseValue.get(callFrame, property); | 2452 result = baseValue.get(callFrame, property); |
| 2493 } | 2453 } |
| 2494 | 2454 |
| 2495 CHECK_FOR_EXCEPTION(); | 2455 CHECK_FOR_EXCEPTION(); |
| 2496 callFrame[dst] = result; | 2456 callFrame[dst] = result; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2510 */ | 2470 */ |
| 2511 int base = (++vPC)->u.operand; | 2471 int base = (++vPC)->u.operand; |
| 2512 int property = (++vPC)->u.operand; | 2472 int property = (++vPC)->u.operand; |
| 2513 int value = (++vPC)->u.operand; | 2473 int value = (++vPC)->u.operand; |
| 2514 | 2474 |
| 2515 JSValuePtr baseValue = callFrame[base].jsValue(callFrame); | 2475 JSValuePtr baseValue = callFrame[base].jsValue(callFrame); |
| 2516 JSValuePtr subscript = callFrame[property].jsValue(callFrame); | 2476 JSValuePtr subscript = callFrame[property].jsValue(callFrame); |
| 2517 | 2477 |
| 2518 if (LIKELY(subscript.isUInt32Fast())) { | 2478 if (LIKELY(subscript.isUInt32Fast())) { |
| 2519 uint32_t i = subscript.getUInt32Fast(); | 2479 uint32_t i = subscript.getUInt32Fast(); |
| 2520 if (isJSArray(baseValue)) { | 2480 if (isJSArray(globalData, baseValue)) { |
| 2521 JSArray* jsArray = asArray(baseValue); | 2481 JSArray* jsArray = asArray(baseValue); |
| 2522 if (jsArray->canSetIndex(i)) | 2482 if (jsArray->canSetIndex(i)) |
| 2523 jsArray->setIndex(i, callFrame[value].jsValue(callFrame)); | 2483 jsArray->setIndex(i, callFrame[value].jsValue(callFrame)); |
| 2524 else | 2484 else |
| 2525 jsArray->JSArray::put(callFrame, i, callFrame[value].jsValue
(callFrame)); | 2485 jsArray->JSArray::put(callFrame, i, callFrame[value].jsValue
(callFrame)); |
| 2526 } else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAc
cessIndex(i)) { | 2486 } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseV
alue)->canAccessIndex(i)) { |
| 2527 JSByteArray* jsByteArray = asByteArray(baseValue); | 2487 JSByteArray* jsByteArray = asByteArray(baseValue); |
| 2528 double dValue = 0; | 2488 double dValue = 0; |
| 2529 JSValuePtr jsValue = callFrame[value].jsValue(callFrame); | 2489 JSValuePtr jsValue = callFrame[value].jsValue(callFrame); |
| 2530 if (jsValue.isInt32Fast()) | 2490 if (jsValue.isInt32Fast()) |
| 2531 jsByteArray->setIndex(i, jsValue.getInt32Fast()); | 2491 jsByteArray->setIndex(i, jsValue.getInt32Fast()); |
| 2532 else if (jsValue.getNumber(dValue)) | 2492 else if (jsValue.getNumber(dValue)) |
| 2533 jsByteArray->setIndex(i, dValue); | 2493 jsByteArray->setIndex(i, dValue); |
| 2534 else | 2494 else |
| 2535 baseValue.put(callFrame, i, jsValue); | 2495 baseValue.put(callFrame, i, jsValue); |
| 2536 } else | 2496 } else |
| (...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3667 if (candidate->callee() == function) | 3627 if (candidate->callee() == function) |
| 3668 return candidate; | 3628 return candidate; |
| 3669 } | 3629 } |
| 3670 return 0; | 3630 return 0; |
| 3671 } | 3631 } |
| 3672 | 3632 |
| 3673 } // namespace JSC | 3633 } // namespace JSC |
| 3674 | 3634 |
| 3675 | 3635 |
| 3676 | 3636 |
| OLD | NEW |