副标题[/!--empirenews.page--]
前言
Javascript中的数组和数组对象一直都是编程人员优化的主要目标,一般来说,数组只会包含一些基本类型数据,比如说32位整数或字符等等。因此,每个引擎都会对这些对象进行某些优化,并提升不同元素类型的访问速度和密集型表示。

在JavaScriptCore中,JavaScript引擎是在WebKit中实现的,其中每一个存储在对象中的元素都代表着一个IndexingType值,一个8位整数代表一套Flag组合,具体的参数定义可以在IndexingType.h中找到。接下来,引擎会检测一个对象中indexing的类型,然后决定使用哪一条快速路径,其中最重要的一种indexing类型就是ArrayWithUndecided,它表示的是所有元素均为未定义(undefined),而且没有存储任何实际的值。在这种情况下,引擎为了提升性能,会让这些元素保持未初始化。
分析
下面,我们一起看一看旧版本中实现Array.prototype.concat的代码(ArrayPrototype.cpp):
- EncodedJSValueJSC_HOST_CALL arrayProtoPrivateFuncConcatMemcpy(ExecState* exec)
- {
- ...
- unsigned resultSize =checkedResultSize.unsafeGet();
- IndexingType firstType =firstArray->indexingType();
- IndexingType secondType =secondArray->indexingType();
- IndexingType type =firstArray->mergeIndexingTypeForCopying(secondType); // [[ 1 ]]
- if (type == NonArray ||!firstArray->canFastCopy(vm, secondArray) || resultSize >=MIN_SPARSE_ARRAY_INDEX) {
- ...
- }
- JSGlobalObject* lexicalGlobalObject =exec->lexicalGlobalObject();
- Structure* resultStructure =lexicalGlobalObject->arrayStructureForIndexingTypeDuringAllocation(type);
- if(UNLIKELY(hasAnyArrayStorage(resultStructure->indexingType())))
- return JSValue::encode(jsNull());
- ASSERT(!lexicalGlobalObject->isHavingABadTime());
- ObjectInitializationScopeinitializationScope(vm);
- JSArray* result =JSArray::tryCreateUninitializedRestricted(initializationScope, resultStructure,resultSize);
- if (UNLIKELY(!result)) {
- throwOutOfMemoryError(exec, scope);
- return encodedJSValue();
- }
- if (type == ArrayWithDouble) {
- [[ 2 ]]
- double* buffer =result->butterfly()->contiguousDouble().data();
- memcpy(buffer,firstButterfly->contiguousDouble().data(), sizeof(JSValue) *firstArraySize);
- memcpy(buffer + firstArraySize,secondButterfly->contiguousDouble().data(), sizeof(JSValue) *secondArraySize);
- } else if (type != ArrayWithUndecided) {
- ...
这个函数主要用来判断结果数组[[1]]的indexing类型,我们可以看到,如果indexing类型为ArrayWithDouble,它将会选择[[2]]作为快速路径。接下来,我们看一看:
mergeIndexingTypeForCopying的实现代码,这个函数主要负责在Array.prototype.concat被调用时,判断结果数组的indexing类型:
- inlineIndexingType JSArray::mergeIndexingTypeForCopying(IndexingType other)
- {
- IndexingType type = indexingType();
- if (!(type & IsArray && other& IsArray))
- return NonArray;
- if (hasAnyArrayStorage(type) ||hasAnyArrayStorage(other))
- return NonArray;
- if (type == ArrayWithUndecided)
- return other; [[ 3 ]]
- ...
(编辑:淮北站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|