Changeset 157420 in webkit
- Timestamp:
- Oct 14, 2013 2:08:37 PM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r157413 r157420 1 2013-10-11 Oliver Hunt <oliver@apple.com> 2 3 Separate out array iteration intrinsics 4 https://bugs.webkit.org/show_bug.cgi?id=122656 5 6 Reviewed by Michael Saboff. 7 8 Separate out the intrinsics for key and values iteration 9 of arrays. 10 11 This requires moving moving array iteration into the iterator 12 instance, rather than the prototype, but this is essentially 13 unobservable so we'll live with it for now. 14 15 * jit/ThunkGenerators.cpp: 16 (JSC::arrayIteratorNextThunkGenerator): 17 (JSC::arrayIteratorNextKeyThunkGenerator): 18 (JSC::arrayIteratorNextValueThunkGenerator): 19 * jit/ThunkGenerators.h: 20 * runtime/ArrayIteratorPrototype.cpp: 21 (JSC::ArrayIteratorPrototype::finishCreation): 22 * runtime/Intrinsic.h: 23 * runtime/JSArrayIterator.cpp: 24 (JSC::JSArrayIterator::finishCreation): 25 (JSC::createIteratorResult): 26 (JSC::arrayIteratorNext): 27 (JSC::arrayIteratorNextKey): 28 (JSC::arrayIteratorNextValue): 29 (JSC::arrayIteratorNextGeneric): 30 * runtime/VM.cpp: 31 (JSC::thunkGeneratorForIntrinsic): 32 1 33 2013-10-11 Mark Hahnenberg <mhahnenberg@apple.com> 2 34 -
trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp
r157317 r157420 989 989 } 990 990 991 MacroAssemblerCodeRef arrayIteratorNextThunkGenerator(VM* vm)991 static MacroAssemblerCodeRef arrayIteratorNextThunkGenerator(VM* vm, ArrayIterationKind kind) 992 992 { 993 993 typedef SpecializedThunkJIT::TrustedImm32 TrustedImm32; … … 1015 1015 1016 1016 jit.and32(TrustedImm32(IndexingShapeMask), SpecializedThunkJIT::regT3); 1017 1017 1018 1018 Jump notDone = jit.branch32(SpecializedThunkJIT::Below, SpecializedThunkJIT::regT1, Address(SpecializedThunkJIT::regT2, Butterfly::offsetOfPublicLength())); 1019 1019 // Return the termination signal to indicate that we've finished … … 1023 1023 notDone.link(&jit); 1024 1024 1025 1026 Jump notKey = jit.branch32(SpecializedThunkJIT::NotEqual, Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfIterationKind()), TrustedImm32(ArrayIterateKey)); 1027 // If we're doing key iteration we just need to increment m_nextIndex and return the current value 1028 jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex())); 1029 jit.returnInt32(SpecializedThunkJIT::regT1); 1030 1031 notKey.link(&jit); 1032 1025 if (kind == ArrayIterateKey) { 1026 jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex())); 1027 jit.returnInt32(SpecializedThunkJIT::regT1); 1028 return jit.finalize(vm->jitStubs->ctiNativeCall(vm), "array-iterator-next-key"); 1029 1030 } 1031 ASSERT(kind == ArrayIterateValue); 1033 1032 1034 1033 // Okay, now we're returning a value so make sure we're inside the vector size … … 1078 1077 jit.returnDouble(SpecializedThunkJIT::fpRegT0); 1079 1078 1080 return jit.finalize(vm->jitStubs->ctiNativeCall(vm), "array-iterator-next"); 1079 return jit.finalize(vm->jitStubs->ctiNativeCall(vm), "array-iterator-next-value"); 1080 } 1081 1082 MacroAssemblerCodeRef arrayIteratorNextKeyThunkGenerator(VM* vm) 1083 { 1084 return arrayIteratorNextThunkGenerator(vm, ArrayIterateKey); 1085 } 1086 1087 MacroAssemblerCodeRef arrayIteratorNextValueThunkGenerator(VM* vm) 1088 { 1089 return arrayIteratorNextThunkGenerator(vm, ArrayIterateValue); 1081 1090 } 1082 1091 -
trunk/Source/JavaScriptCore/jit/ThunkGenerators.h
r157317 r157420 59 59 MacroAssemblerCodeRef powThunkGenerator(VM*); 60 60 MacroAssemblerCodeRef imulThunkGenerator(VM*); 61 MacroAssemblerCodeRef arrayIteratorNextThunkGenerator(VM*); 61 MacroAssemblerCodeRef arrayIteratorNextKeyThunkGenerator(VM*); 62 MacroAssemblerCodeRef arrayIteratorNextValueThunkGenerator(VM*); 62 63 63 64 } -
trunk/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp
r157317 r157420 37 37 const ClassInfo ArrayIteratorPrototype::s_info = { "Array Iterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArrayIteratorPrototype) }; 38 38 39 static EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeNext(ExecState*);40 39 static EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeIterate(ExecState*); 41 40 … … 46 45 vm.prototypeMap.addPrototype(this); 47 46 48 JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorPrototypeNext, DontEnum, 0, ArrayIteratorNextIntrinsic);49 50 47 JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, arrayIteratorPrototypeIterate, DontEnum, 0); 51 }52 53 static EncodedJSValue createIteratorResult(CallFrame* callFrame, ArrayIterationKind kind, size_t index, JSValue result, bool done)54 {55 callFrame->setArgument(callFrame->argumentCount() - 1, jsBoolean(done));56 if (done)57 return JSValue::encode(callFrame->vm().iterationTerminator.get());58 59 switch (kind & ~ArrayIterateSparseTag) {60 case ArrayIterateKey:61 return JSValue::encode(jsNumber(index));62 63 case ArrayIterateValue:64 return JSValue::encode(result);65 66 case ArrayIterateKeyValue: {67 MarkedArgumentBuffer args;68 args.append(jsNumber(index));69 args.append(result);70 JSGlobalObject* globalObject = callFrame->callee()->globalObject();71 return JSValue::encode(constructArray(callFrame, 0, globalObject, args));72 73 }74 default:75 RELEASE_ASSERT_NOT_REACHED();76 }77 return JSValue::encode(JSValue());78 }79 80 EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeNext(CallFrame* callFrame)81 {82 JSArrayIterator* iterator = jsDynamicCast<JSArrayIterator*>(callFrame->thisValue());83 if (!iterator)84 throwTypeError(callFrame, ASCIILiteral("Cannot call ArrayIterator.next() on a non-ArrayIterator object"));85 JSObject* iteratedObject = iterator->iteratedObject();86 size_t index = iterator->nextIndex();87 ArrayIterationKind kind = iterator->iterationKind();88 JSValue jsLength = JSValue(iteratedObject).get(callFrame, callFrame->propertyNames().length);89 if (callFrame->hadException())90 return JSValue::encode(jsNull());91 92 size_t length = jsLength.toUInt32(callFrame);93 if (callFrame->hadException())94 return JSValue::encode(jsNull());95 96 if (index >= length) {97 iterator->finish();98 return createIteratorResult(callFrame, kind, index, jsUndefined(), true);99 }100 if (JSValue result = iteratedObject->tryGetIndexQuickly(index)) {101 iterator->setNextIndex(index + 1);102 return createIteratorResult(callFrame, kind, index, result, false);103 }104 105 JSValue result = jsUndefined();106 PropertySlot slot(iteratedObject);107 if (kind > ArrayIterateSparseTag) {108 // We assume that the indexed property will be an own property so cache the getOwnProperty109 // method locally110 auto getOwnPropertySlotByIndex = iteratedObject->methodTable()->getOwnPropertySlotByIndex;111 while (index < length) {112 if (getOwnPropertySlotByIndex(iteratedObject, callFrame, index, slot)) {113 result = slot.getValue(callFrame, index);114 break;115 }116 if (iteratedObject->getPropertySlot(callFrame, index, slot)) {117 result = slot.getValue(callFrame, index);118 break;119 }120 index++;121 }122 } else if (iteratedObject->getPropertySlot(callFrame, index, slot))123 result = slot.getValue(callFrame, index);124 125 if (index == length)126 iterator->finish();127 else128 iterator->setNextIndex(index + 1);129 return createIteratorResult(callFrame, kind, index, jsUndefined(), index == length);130 48 } 131 49 -
trunk/Source/JavaScriptCore/runtime/Intrinsic.h
r157317 r157420 50 50 StringPrototypeValueOfIntrinsic, 51 51 IMulIntrinsic, 52 ArrayIteratorNextIntrinsic 52 ArrayIteratorNextValueIntrinsic, 53 ArrayIteratorNextKeyIntrinsic, 54 ArrayIteratorNextGenericIntrinsic 53 55 }; 54 56 -
trunk/Source/JavaScriptCore/runtime/JSArrayIterator.cpp
r157317 r157420 35 35 const ClassInfo JSArrayIterator::s_info = { "ArrayIterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSArrayIterator) }; 36 36 37 void JSArrayIterator::finishCreation(VM& vm, JSGlobalObject*, ArrayIterationKind kind, JSObject* iteratedObject) 37 static EncodedJSValue JSC_HOST_CALL arrayIteratorNextKey(ExecState*); 38 static EncodedJSValue JSC_HOST_CALL arrayIteratorNextValue(ExecState*); 39 static EncodedJSValue JSC_HOST_CALL arrayIteratorNextGeneric(ExecState*); 40 41 void JSArrayIterator::finishCreation(VM& vm, JSGlobalObject* globalObject, ArrayIterationKind kind, JSObject* iteratedObject) 38 42 { 39 43 Base::finishCreation(vm); 44 ASSERT(inherits(info())); 40 45 m_iterationKind = kind; 41 46 m_iteratedObject.set(vm, this, iteratedObject); 47 switch (kind) { 48 case ArrayIterateKey: 49 JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextKey, DontEnum, 0, ArrayIteratorNextKeyIntrinsic); 50 break; 51 case ArrayIterateValue: 52 JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextValue, DontEnum, 0, ArrayIteratorNextValueIntrinsic); 53 break; 54 default: 55 JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextGeneric, DontEnum, 0, ArrayIteratorNextGenericIntrinsic); 56 break; 57 } 58 42 59 } 43 60 … … 55 72 } 56 73 74 static EncodedJSValue createIteratorResult(CallFrame* callFrame, ArrayIterationKind kind, size_t index, JSValue result, bool done) 75 { 76 callFrame->setArgument(callFrame->argumentCount() - 1, jsBoolean(done)); 77 if (done) 78 return JSValue::encode(callFrame->vm().iterationTerminator.get()); 79 80 switch (kind & ~ArrayIterateSparseTag) { 81 case ArrayIterateKey: 82 return JSValue::encode(jsNumber(index)); 83 84 case ArrayIterateValue: 85 return JSValue::encode(result); 86 87 case ArrayIterateKeyValue: { 88 MarkedArgumentBuffer args; 89 args.append(jsNumber(index)); 90 args.append(result); 91 JSGlobalObject* globalObject = callFrame->callee()->globalObject(); 92 return JSValue::encode(constructArray(callFrame, 0, globalObject, args)); 93 94 } 95 default: 96 RELEASE_ASSERT_NOT_REACHED(); 97 } 98 return JSValue::encode(JSValue()); 57 99 } 100 101 static inline EncodedJSValue JSC_HOST_CALL arrayIteratorNext(CallFrame* callFrame) 102 { 103 JSArrayIterator* iterator = jsDynamicCast<JSArrayIterator*>(callFrame->thisValue()); 104 if (!iterator) 105 throwTypeError(callFrame, ASCIILiteral("Cannot call ArrayIterator.next() on a non-ArrayIterator object")); 106 JSObject* iteratedObject = iterator->iteratedObject(); 107 size_t index = iterator->nextIndex(); 108 ArrayIterationKind kind = iterator->iterationKind(); 109 JSValue jsLength = JSValue(iteratedObject).get(callFrame, callFrame->propertyNames().length); 110 if (callFrame->hadException()) 111 return JSValue::encode(jsNull()); 112 113 size_t length = jsLength.toUInt32(callFrame); 114 if (callFrame->hadException()) 115 return JSValue::encode(jsNull()); 116 117 if (index >= length) { 118 iterator->finish(); 119 return createIteratorResult(callFrame, kind, index, jsUndefined(), true); 120 } 121 if (JSValue result = iteratedObject->tryGetIndexQuickly(index)) { 122 iterator->setNextIndex(index + 1); 123 return createIteratorResult(callFrame, kind, index, result, false); 124 } 125 126 JSValue result = jsUndefined(); 127 PropertySlot slot(iteratedObject); 128 if (kind > ArrayIterateSparseTag) { 129 // We assume that the indexed property will be an own property so cache the getOwnProperty 130 // method locally 131 auto getOwnPropertySlotByIndex = iteratedObject->methodTable()->getOwnPropertySlotByIndex; 132 while (index < length) { 133 if (getOwnPropertySlotByIndex(iteratedObject, callFrame, index, slot)) { 134 result = slot.getValue(callFrame, index); 135 break; 136 } 137 if (iteratedObject->getPropertySlot(callFrame, index, slot)) { 138 result = slot.getValue(callFrame, index); 139 break; 140 } 141 index++; 142 } 143 } else if (iteratedObject->getPropertySlot(callFrame, index, slot)) 144 result = slot.getValue(callFrame, index); 145 146 if (index == length) 147 iterator->finish(); 148 else 149 iterator->setNextIndex(index + 1); 150 return createIteratorResult(callFrame, kind, index, jsUndefined(), index == length); 151 } 152 153 EncodedJSValue JSC_HOST_CALL arrayIteratorNextKey(CallFrame* callFrame) 154 { 155 return arrayIteratorNext(callFrame); 156 } 157 158 EncodedJSValue JSC_HOST_CALL arrayIteratorNextValue(CallFrame* callFrame) 159 { 160 return arrayIteratorNext(callFrame); 161 } 162 163 EncodedJSValue JSC_HOST_CALL arrayIteratorNextGeneric(CallFrame* callFrame) 164 { 165 return arrayIteratorNext(callFrame); 166 } 167 168 } -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r157317 r157420 426 426 case IMulIntrinsic: 427 427 return imulThunkGenerator; 428 case ArrayIteratorNextIntrinsic: 429 return arrayIteratorNextThunkGenerator; 428 case ArrayIteratorNextKeyIntrinsic: 429 return arrayIteratorNextKeyThunkGenerator; 430 case ArrayIteratorNextValueIntrinsic: 431 return arrayIteratorNextValueThunkGenerator; 430 432 default: 431 433 return 0;
Note: See TracChangeset
for help on using the changeset viewer.