diff options
Diffstat (limited to 'JavaScriptCore')
26 files changed, 861 insertions, 281 deletions
diff --git a/JavaScriptCore/CMakeLists.txt b/JavaScriptCore/CMakeLists.txt index 08a0e72..c33146d 100644 --- a/JavaScriptCore/CMakeLists.txt +++ b/JavaScriptCore/CMakeLists.txt @@ -265,5 +265,6 @@ TARGET_LINK_LIBRARIES(${JavaScriptCore_LIBRARY_NAME} ${JavaScriptCore_LIBRARIES} ADD_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} LINK_FLAGS ${JavaScriptCore_LINK_FLAGS}) IF (SHARED_CORE) + SET_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) INSTALL(TARGETS ${JavaScriptCore_LIBRARY_NAME} DESTINATION lib) ENDIF () diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog index 2e8c1d1..aafb0aa 100644 --- a/JavaScriptCore/ChangeLog +++ b/JavaScriptCore/ChangeLog @@ -1,3 +1,284 @@ +2010-08-02 Mahesh Kulkarni <mahesh.kulkarni@nokia.com> + + Reviewed by Simon Hausmann. + + [QT] build fix for symbian + https://bugs.webkit.org/show_bug.cgi?id=43234 + + 1) wrong order of passing param's + 2) static_cast complains on symbian so using reinterpret_cast + + No new tests added. Just a build fix for qt symbian + + * wtf/PageAllocation.cpp: + (WTF::PageAllocation::commit): + (WTF::PageAllocation::decommit): + (WTF::PageAllocation::reserve): + +2010-07-30 Luiz Agostini <luiz.agostini@openbossa.org> + + Reviewed by Simon Fraser. + + Enabling view modes to all platforms + https://bugs.webkit.org/show_bug.cgi?id=37505 + + Removing ENABLE_WIDGETS_10_SUPPORT flag. + + As view mode media feature is not part of widget 1.0 specification + any more the ENABLE_WIDGETS_10_SUPPORT flag may be removed. The only use + of this flag was related to view mode media feature implementation in Qt. + + * wtf/Platform.h: + +2010-07-30 Andy Estes <aestes@apple.com> + + Reviewed by David Kilzer. + + Add Xcode support for compiling WebKit against iOS SDKs. + https://bugs.webkit.org/show_bug.cgi?id=42796 + + * Configurations/Base.xcconfig: + * Configurations/DebugRelease.xcconfig: + * Configurations/FeatureDefines.xcconfig: + +2010-07-30 Dumitru Daniliuc <dumi@chromium.org> + + Reviewed by Davin Levin. + + Added a yield() function. + https://bugs.webkit.org/show_bug.cgi?id=42843 + + * JavaScriptCore.exp: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * wtf/Threading.h: + * wtf/ThreadingPthreads.cpp: + (WTF::yield): + * wtf/ThreadingWin.cpp: + (WTF::yield): + * wtf/gtk/ThreadingGtk.cpp: + (WTF::yield): + * wtf/qt/ThreadingQt.cpp: + (WTF::yield): + +2010-07-30 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] Add library version and soname to EFL generated libraries and binary. + https://bugs.webkit.org/show_bug.cgi?id=43212 + + Add version and soname to libjavascriptcore.so and libwtf.so in case of + linking as shared libraries, and version to jsc executable. + + * CMakeLists.txt: + * jsc/CMakeLists.txt: + * wtf/CMakeLists.txt: + +2010-07-30 Mahesh Kulkarni <mahesh.kulkarni@nokia.com> + + Reviewed by Simon Hausmann. + + [QT] build fix for symbian + https://bugs.webkit.org/show_bug.cgi?id=43234 + + * wtf/PageAllocation.h: + (WTF::PageAllocation::PageAllocation): + +2010-07-29 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r64313. + http://trac.webkit.org/changeset/64313 + https://bugs.webkit.org/show_bug.cgi?id=43233 + + Some Chromium bots are not happy with it for some unknown + reason. (Requested by dumi on #webkit). + + * JavaScriptCore.exp: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * wtf/Threading.h: + * wtf/ThreadingPthreads.cpp: + * wtf/ThreadingWin.cpp: + * wtf/gtk/ThreadingGtk.cpp: + * wtf/qt/ThreadingQt.cpp: + +2010-07-29 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r64302. + http://trac.webkit.org/changeset/64302 + https://bugs.webkit.org/show_bug.cgi?id=43223 + + Assertion is bogus (Requested by olliej on #webkit). + + * assembler/ARMAssembler.cpp: + (JSC::ARMAssembler::executableCopy): + * assembler/AssemblerBuffer.h: + (JSC::AssemblerBuffer::putShortUnchecked): + (JSC::AssemblerBuffer::putIntUnchecked): + (JSC::AssemblerBuffer::putInt64Unchecked): + * jit/JITStubs.cpp: + * pcre/pcre_compile.cpp: + (jsRegExpCompile): + * wtf/FastMalloc.cpp: + (WTF::PageHeapAllocator::New): + (WTF::TCMalloc_Central_FreeList::Populate): + * wtf/MD5.cpp: + (WTF::reverseBytes): + (WTF::MD5::addBytes): + (WTF::MD5::checksum): + * wtf/StdLibExtras.h: + * wtf/Vector.h: + (WTF::VectorBuffer::inlineBuffer): + * wtf/qt/StringQt.cpp: + (WebCore::String::String): + +2010-07-29 Michael Saboff <msaboff@apple.com> + + Reviewed by Gavin Barraclough. + + Changed the handling for removing and adding elements at the front + of an array. The code now keeps a bias that indicates the amount of + JSValue sized holes are prior to the ArrayStorage block. This means + that shift operations are now memmove's of the header part of + the ArrayStorage and unshift operations are similar, but may require a + realloc first to create the space. Similar operations are performed + for special cases of splice and slice. + Also optimized the new Array(size) case so that we don't allocate and + initialize array elements until the JS code starts using elements. + The array growth code is slightly more aggressive for initial growth + based on size growth of any previous array. + + * Configurations/JavaScriptCore.xcconfig: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncShift): + (JSC::arrayProtoFuncSplice): + (JSC::arrayProtoFuncUnShift): + * runtime/JSArray.cpp: + (JSC::JSArray::JSArray): + (JSC::JSArray::~JSArray): + (JSC::JSArray::getOwnPropertySlot): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::put): + (JSC::JSArray::putSlowCase): + (JSC::JSArray::deleteProperty): + (JSC::JSArray::getOwnPropertyNames): + (JSC::JSArray::getNewVectorLength): + (JSC::JSArray::increaseVectorLength): + (JSC::JSArray::increaseVectorPrefixLength): + (JSC::JSArray::setLength): + (JSC::JSArray::pop): + (JSC::JSArray::push): + (JSC::JSArray::shiftCount): + (JSC::JSArray::unshiftCount): + (JSC::JSArray::sortNumeric): + (JSC::JSArray::sort): + (JSC::JSArray::fillArgList): + (JSC::JSArray::copyToRegisters): + (JSC::JSArray::compactForSorting): + (JSC::JSArray::subclassData): + (JSC::JSArray::setSubclassData): + (JSC::JSArray::checkConsistency): + * runtime/JSArray.h: + (JSC::JSArray::length): + (JSC::JSArray::canGetIndex): + (JSC::JSArray::getIndex): + (JSC::JSArray::setIndex): + (JSC::JSArray::uncheckedSetIndex): + (JSC::JSArray::arrayStorage): + (JSC::JSArray::setArrayStorage): + (JSC::JSArray::markChildrenDirect): + +2010-07-29 Michael Saboff <msaboff@apple.com> + + Reviewed by Darin Adler. + + Changed MINIMUM_CELL_SIZE to be fixed at 64 bytes. + + * runtime/Collector.h: + +2010-07-28 Dumitru Daniliuc <dumi@chromium.org> + + Reviewed by David Levin. + + Added a yield() function. + https://bugs.webkit.org/show_bug.cgi?id=42843 + + * JavaScriptCore.exp: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * wtf/Threading.h: + * wtf/ThreadingPthreads.cpp: + (WTF::yield): + * wtf/ThreadingWin.cpp: + (WTF::yield): + * wtf/gtk/ThreadingGtk.cpp: + (WTF::yield): + * wtf/qt/ThreadingQt.cpp: + (WTF::yield): + +2010-07-29 Michael Saboff <msaboff@apple.com> + + Reviewed by Oliver Hunt. + + Fixed issue where RegExp greedy jit code loops when no input is + consumed. Changed the code to only loop if some input was consumed, + but fall through if we successfully match an alternative that + doesn't consume any input. + https://bugs.webkit.org/show_bug.cgi?id=42664 + + * yarr/RegexJIT.cpp: + (JSC::Yarr::RegexGenerator::generateParenthesesGreedyNoBacktrack): + +2010-07-29 Gabor Loki <loki@webkit.org> + + Reviewed by Gavin Barraclough. + + Avoid increasing required alignment of target type warning on ARM + https://bugs.webkit.org/show_bug.cgi?id=38045 + + The reinterpret_cast<Type1*>([pointer to Type2]) expressions - where + sizeof(Type1) > sizeof(Type2) - cause the following warning on ARM: + increases required alignment of target type warnings. + Casting the type of [pointer to Type2] object to void* bypasses the + warning. + + * assembler/ARMAssembler.cpp: + (JSC::ARMAssembler::executableCopy): + * assembler/AssemblerBuffer.h: + (JSC::AssemblerBuffer::putShortUnchecked): + (JSC::AssemblerBuffer::putIntUnchecked): + (JSC::AssemblerBuffer::putInt64Unchecked): + * jit/JITStubs.cpp: + * pcre/pcre_compile.cpp: + (jsRegExpCompile): + * wtf/FastMalloc.cpp: + (WTF::PageHeapAllocator::New): + (WTF::TCMalloc_Central_FreeList::Populate): + * wtf/MD5.cpp: + (WTF::reverseBytes): + (WTF::MD5::addBytes): + (WTF::MD5::checksum): + * wtf/StdLibExtras.h: + (reinterpret_cast_ptr): + * wtf/Vector.h: + (WTF::VectorBuffer::inlineBuffer): + * wtf/qt/StringQt.cpp: + (WebCore::String::String): + +2010-07-29 Martin Robinson <mrobinson@igalia.com> + + Unreviewed build fix. + + Include a missing header in the source list to fix 'make dist.' + + * GNUmakefile.am: Include missing header. + 2010-07-28 Gavin Barraclough <barraclough@apple.com> Reviewed by Darin Adler. diff --git a/JavaScriptCore/Configurations/Base.xcconfig b/JavaScriptCore/Configurations/Base.xcconfig index 4854b64..72de2fe 100644 --- a/JavaScriptCore/Configurations/Base.xcconfig +++ b/JavaScriptCore/Configurations/Base.xcconfig @@ -1,4 +1,4 @@ -// Copyright (C) 2009 Apple Inc. All rights reserved. +// Copyright (C) 2009, 2010 Apple Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions @@ -36,7 +36,8 @@ GCC_ENABLE_SYMBOL_SEPARATION = NO; GCC_FAST_OBJC_DISPATCH = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; -GCC_MODEL_TUNING = G5; +GCC_MODEL_TUNING = $(GCC_MODEL_TUNING_$(REAL_PLATFORM_NAME)); +GCC_MODEL_TUNING_macosx = G5; GCC_OBJC_CALL_CXX_CDTORS = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) HAVE_DTRACE=$(HAVE_DTRACE) WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST $(GCC_PREPROCESSOR_DEFINITIONS); @@ -49,15 +50,21 @@ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; LINKER_DISPLAYS_MANGLED_NAMES = YES; PREBINDING = NO; -VALID_ARCHS = i386 ppc x86_64 ppc64 $(ARCHS_UNIVERSAL_IPHONE_OS); -WARNING_CFLAGS = $(WARNING_CFLAGS_$(CURRENT_ARCH)); -WARNING_CFLAGS_BASE = -Wall -Wextra -Wcast-align -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings; -WARNING_CFLAGS_ = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32; -WARNING_CFLAGS_i386 = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32; -WARNING_CFLAGS_ppc = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32; +VALID_ARCHS = $(VALID_ARCHS_$(REAL_PLATFORM_NAME)); +VALID_ARCHS_iphoneos = $(ARCHS_STANDARD_32_BIT); +VALID_ARCHS_iphonesimulator = $(ARCHS_STANDARD_32_BIT); +VALID_ARCHS_macosx = i386 ppc x86_64 ppc64 $(ARCHS_UNIVERSAL_IPHONE_OS); +WARNING_CFLAGS_BASE = -Wall -Wextra -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings; +WARNING_CFLAGS = $(WARNING_CFLAGS_$(REAL_PLATFORM_NAME)); +WARNING_CFLAGS_iphoneos = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32; +WARNING_CFLAGS_iphonesimulator = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32; +WARNING_CFLAGS_macosx = $(WARNING_CFLAGS_macosx_$(CURRENT_ARCH)); +WARNING_CFLAGS_macosx_ = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32; +WARNING_CFLAGS_macosx_i386 = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32; +WARNING_CFLAGS_macosx_ppc = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32; // FIXME: JavaScriptCore 64-bit builds should build with -Wshorten-64-to-32 -WARNING_CFLAGS_ppc64 = $(WARNING_CFLAGS_BASE); -WARNING_CFLAGS_x86_64 = $(WARNING_CFLAGS_BASE); +WARNING_CFLAGS_macosx_ppc64 = $(WARNING_CFLAGS_BASE) -Wcast-align; +WARNING_CFLAGS_macosx_x86_64 = $(WARNING_CFLAGS_BASE) -Wcast-align; HEADER_SEARCH_PATHS = . icu $(HEADER_SEARCH_PATHS); @@ -94,15 +101,18 @@ SECTORDER_FLAGS = -sectorder __TEXT __text JavaScriptCore.order; // Note that Xcode versions as new as 3.1.2 use XCODE_VERSION_ACTUAL for the minor version // number. Newer versions of Xcode use XCODE_VERSION_MINOR for the minor version, and // XCODE_VERSION_ACTUAL for the full version number. -TARGET_GCC_VERSION = $(TARGET_GCC_VERSION_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -TARGET_GCC_VERSION_ = $(TARGET_GCC_VERSION_1040); -TARGET_GCC_VERSION_1040 = GCC_40; -TARGET_GCC_VERSION_1050 = $(TARGET_GCC_VERSION_1050_$(XCODE_VERSION_MINOR)); -TARGET_GCC_VERSION_1050_ = $(TARGET_GCC_VERSION_1050_$(XCODE_VERSION_ACTUAL)); -TARGET_GCC_VERSION_1050_0310 = GCC_42; -TARGET_GCC_VERSION_1050_0320 = GCC_42; -TARGET_GCC_VERSION_1060 = GCC_42; -TARGET_GCC_VERSION_1070 = LLVM_GCC_42; +TARGET_GCC_VERSION = $(TARGET_GCC_VERSION_$(REAL_PLATFORM_NAME)); +TARGET_GCC_VERSION_iphoneos = LLVM_GCC_42; +TARGET_GCC_VERSION_iphonesimulator = GCC_42; +TARGET_GCC_VERSION_macosx = $(TARGET_GCC_VERSION_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR)); +TARGET_GCC_VERSION_macosx_ = $(TARGET_GCC_VERSION_macosx_1040); +TARGET_GCC_VERSION_macosx_1040 = GCC_40; +TARGET_GCC_VERSION_macosx_1050 = $(TARGET_GCC_VERSION_macosx_1050_$(XCODE_VERSION_MINOR)); +TARGET_GCC_VERSION_macosx_1050_ = $(TARGET_GCC_VERSION_macosx_1050_$(XCODE_VERSION_ACTUAL)); +TARGET_GCC_VERSION_macosx_1050_0310 = GCC_42; +TARGET_GCC_VERSION_macosx_1050_0320 = GCC_42; +TARGET_GCC_VERSION_macosx_1060 = GCC_42; +TARGET_GCC_VERSION_macosx_1070 = LLVM_GCC_42; GCC_VERSION = $(GCC_VERSION_$(TARGET_GCC_VERSION)); GCC_VERSION_GCC_40 = 4.0; @@ -122,7 +132,7 @@ SDKROOT_1070_1060 = macosx10.6; // HAVE_DTRACE is disabled on Leopard due to <rdar://problem/5628149> HAVE_DTRACE = $(HAVE_DTRACE_$(REAL_PLATFORM_NAME)); HAVE_DTRACE_iphoneos = 1; -HAVE_DTRACE_iphonesimulator = 0; +HAVE_DTRACE_iphonesimulator = 1; HAVE_DTRACE_macosx = $(HAVE_DTRACE_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR)); HAVE_DTRACE_macosx_ = $(HAVE_DTRACE_macosx_1040); HAVE_DTRACE_macosx_1040 = 0; diff --git a/JavaScriptCore/Configurations/DebugRelease.xcconfig b/JavaScriptCore/Configurations/DebugRelease.xcconfig index 1e981f8..a98e1ce 100644 --- a/JavaScriptCore/Configurations/DebugRelease.xcconfig +++ b/JavaScriptCore/Configurations/DebugRelease.xcconfig @@ -1,4 +1,4 @@ -// Copyright (C) 2009 Apple Inc. All rights reserved. +// Copyright (C) 2009, 2010 Apple Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions @@ -35,12 +35,15 @@ ARCHS_macosx_1070 = $(ARCHS_STANDARD_32_64_BIT); ONLY_ACTIVE_ARCH = YES; -MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -MACOSX_DEPLOYMENT_TARGET_ = 10.4; -MACOSX_DEPLOYMENT_TARGET_1040 = 10.4; -MACOSX_DEPLOYMENT_TARGET_1050 = 10.5; -MACOSX_DEPLOYMENT_TARGET_1060 = 10.6; -MACOSX_DEPLOYMENT_TARGET_1070 = 10.7; +MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(REAL_PLATFORM_NAME)); +MACOSX_DEPLOYMENT_TARGET_iphoneos = 10.5; +MACOSX_DEPLOYMENT_TARGET_iphonesimulator = 10.5; +MACOSX_DEPLOYMENT_TARGET_macosx = $(MACOSX_DEPLOYMENT_TARGET_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR)); +MACOSX_DEPLOYMENT_TARGET_macosx_ = 10.4; +MACOSX_DEPLOYMENT_TARGET_macosx_1040 = 10.4; +MACOSX_DEPLOYMENT_TARGET_macosx_1050 = 10.5; +MACOSX_DEPLOYMENT_TARGET_macosx_1060 = 10.6; +MACOSX_DEPLOYMENT_TARGET_macosx_1070 = 10.7; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; diff --git a/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/JavaScriptCore/Configurations/FeatureDefines.xcconfig index 8e33a91..9810cf7 100644 --- a/JavaScriptCore/Configurations/FeatureDefines.xcconfig +++ b/JavaScriptCore/Configurations/FeatureDefines.xcconfig @@ -1,4 +1,4 @@ -// Copyright (C) 2009 Apple Inc. All rights reserved. +// Copyright (C) 2009, 2010 Apple Inc. All rights reserved. // Copyright (C) 2009 Google Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -33,31 +33,52 @@ ENABLE_LINK_PREFETCH = ; -ENABLE_3D_CANVAS = $(ENABLE_3D_CANVAS_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -ENABLE_3D_CANVAS_1060 = ENABLE_3D_CANVAS; -ENABLE_3D_CANVAS_1070 = ENABLE_3D_CANVAS; +ENABLE_3D_CANVAS = $(ENABLE_3D_CANVAS_$(REAL_PLATFORM_NAME)); +ENABLE_3D_CANVAS_macosx = $(ENABLE_3D_CANVAS_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR)); +ENABLE_3D_CANVAS_macosx_1060 = ENABLE_3D_CANVAS; +ENABLE_3D_CANVAS_macosx_1070 = ENABLE_3D_CANVAS; -ENABLE_3D_RENDERING = $(ENABLE_3D_RENDERING_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -ENABLE_3D_RENDERING_1050 = ENABLE_3D_RENDERING; -ENABLE_3D_RENDERING_1060 = ENABLE_3D_RENDERING; -ENABLE_3D_RENDERING_1070 = ENABLE_3D_RENDERING; +ENABLE_3D_RENDERING = $(ENABLE_3D_RENDERING_$(REAL_PLATFORM_NAME)); +ENABLE_3D_RENDERING_iphoneos = ENABLE_3D_RENDERING; +ENABLE_3D_RENDERING_iphonesimulator = $(ENABLE_3D_RENDERING_iphoneos); +ENABLE_3D_RENDERING_macosx = $(ENABLE_3D_RENDERING_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR)); +ENABLE_3D_RENDERING_macosx_1050 = ENABLE_3D_RENDERING; +ENABLE_3D_RENDERING_macosx_1060 = ENABLE_3D_RENDERING; +ENABLE_3D_RENDERING_macosx_1070 = ENABLE_3D_RENDERING; + +ENABLE_BLOB_SLICE = $(ENABLE_BLOB_SLICE_$(REAL_PLATFORM_NAME)); +ENABLE_BLOB_SLICE_macosx = ENABLE_BLOB_SLICE; + +ENABLE_CHANNEL_MESSAGING = $(ENABLE_CHANNEL_MESSAGING_$(REAL_PLATFORM_NAME)); +ENABLE_CHANNEL_MESSAGING_macosx = ENABLE_CHANNEL_MESSAGING; + +ENABLE_CLIENT_BASED_GEOLOCATION = $(ENABLE_CLIENT_BASED_GEOLOCATION_$(REAL_PLATFORM_NAME)); +ENABLE_CLIENT_BASED_GEOLOCATION_macosx = ENABLE_CLIENT_BASED_GEOLOCATION; -ENABLE_BLOB_SLICE = ENABLE_BLOB_SLICE; -ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING; -ENABLE_CLIENT_BASED_GEOLOCATION = ENABLE_CLIENT_BASED_GEOLOCATION; ENABLE_DATABASE = ENABLE_DATABASE; ENABLE_DATAGRID = ; -ENABLE_DATALIST = ENABLE_DATALIST; + +ENABLE_DATALIST = $(ENABLE_DATALIST_$(REAL_PLATFORM_NAME)); +ENABLE_DATALIST_macosx = ENABLE_DATALIST; + ENABLE_DEVICE_ORIENTATION = ; ENABLE_DIRECTORY_UPLOAD = ; ENABLE_DOM_STORAGE = ENABLE_DOM_STORAGE; ENABLE_EVENTSOURCE = ENABLE_EVENTSOURCE; -ENABLE_FILTERS = ENABLE_FILTERS; -ENABLE_FILE_READER = ENABLE_FILE_READER; + +ENABLE_FILTERS = $(ENABLE_FILTERS_$(REAL_PLATFORM_NAME)); +ENABLE_FILTERS_macosx = ENABLE_FILTERS; + +ENABLE_FILE_READER = $(ENABLE_FILE_READER_$(REAL_PLATFORM_NAME)); +ENABLE_FILE_READER_macosx = ENABLE_FILE_READER; + ENABLE_FILE_WRITER = ; ENABLE_FILE_SYSTEM = ; ENABLE_GEOLOCATION = ENABLE_GEOLOCATION; -ENABLE_ICONDATABASE = ENABLE_ICONDATABASE; + +ENABLE_ICONDATABASE = $(ENABLE_ICONDATABASE_$(REAL_PLATFORM_NAME)); +ENABLE_ICONDATABASE_macosx = ENABLE_ICONDATABASE; + ENABLE_IMAGE_RESIZER = ; ENABLE_INDEXED_DATABASE = ; ENABLE_INPUT_SPEECH = ; @@ -67,21 +88,37 @@ ENABLE_METER_TAG = ENABLE_METER_TAG; ENABLE_NOTIFICATIONS = ; ENABLE_OFFLINE_WEB_APPLICATIONS = ENABLE_OFFLINE_WEB_APPLICATIONS; ENABLE_PROGRESS_TAG = ENABLE_PROGRESS_TAG; -ENABLE_RUBY = ENABLE_RUBY; -ENABLE_SANDBOX = ENABLE_SANDBOX; -ENABLE_SHARED_WORKERS = ENABLE_SHARED_WORKERS; + +ENABLE_RUBY = $(ENABLE_RUBY_$(REAL_PLATFORM_NAME)); +ENABLE_RUBY_macosx = ENABLE_RUBY; + +ENABLE_SANDBOX = $(ENABLE_SANDBOX_$(REAL_PLATFORM_NAME)); +ENABLE_SANDBOX_macosx = ENABLE_SANDBOX; + +ENABLE_SHARED_WORKERS = $(ENABLE_SHARED_WORKERS_$(REAL_PLATFORM_NAME)); +ENABLE_SHARED_WORKERS_macosx = ENABLE_SHARED_WORKERS; + ENABLE_SVG = ENABLE_SVG; ENABLE_SVG_ANIMATION = ENABLE_SVG_ANIMATION; ENABLE_SVG_AS_IMAGE = ENABLE_SVG_AS_IMAGE; -ENABLE_SVG_DOM_OBJC_BINDINGS = ENABLE_SVG_DOM_OBJC_BINDINGS; + +ENABLE_SVG_DOM_OBJC_BINDINGS = $(ENABLE_SVG_DOM_OBJC_BINDINGS_$(REAL_PLATFORM_NAME)); +ENABLE_SVG_DOM_OBJC_BINDINGS_macosx = ENABLE_SVG_DOM_OBJC_BINDINGS; + ENABLE_SVG_FONTS = ENABLE_SVG_FONTS; ENABLE_SVG_FOREIGN_OBJECT = ENABLE_SVG_FOREIGN_OBJECT; ENABLE_SVG_USE = ENABLE_SVG_USE; ENABLE_VIDEO = ENABLE_VIDEO; -ENABLE_WEB_SOCKETS = ENABLE_WEB_SOCKETS; + +ENABLE_WEB_SOCKETS = $(ENABLE_WEB_SOCKETS_$(REAL_PLATFORM_NAME)); +ENABLE_WEB_SOCKETS_macosx = ENABLE_WEB_SOCKETS; + ENABLE_WEB_TIMING = ; ENABLE_WML = ; -ENABLE_WORKERS = ENABLE_WORKERS; + +ENABLE_WORKERS = $(ENABLE_WORKERS_$(REAL_PLATFORM_NAME)); +ENABLE_WORKERS_macosx = ENABLE_WORKERS; + ENABLE_XHTMLMP = ; ENABLE_XPATH = ENABLE_XPATH; ENABLE_XSLT = ENABLE_XSLT; diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig index c1b6b32..2893a3c 100644 --- a/JavaScriptCore/Configurations/Version.xcconfig +++ b/JavaScriptCore/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 534; -MINOR_VERSION = 4; +MINOR_VERSION = 5; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am index 98f491c..1dd15e4 100644 --- a/JavaScriptCore/GNUmakefile.am +++ b/JavaScriptCore/GNUmakefile.am @@ -409,6 +409,7 @@ javascriptcore_sources += \ JavaScriptCore/wtf/Assertions.h \ JavaScriptCore/wtf/Atomics.h \ JavaScriptCore/wtf/AVLTree.h \ + JavaScriptCore/wtf/BumpPointerAllocator.h \ JavaScriptCore/wtf/ByteArray.cpp \ JavaScriptCore/wtf/ByteArray.h \ JavaScriptCore/wtf/CrossThreadRefCounted.h \ diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp index 93e01e2..b66d8df 100644 --- a/JavaScriptCore/JavaScriptCore.exp +++ b/JavaScriptCore/JavaScriptCore.exp @@ -367,6 +367,7 @@ __ZN3WTF5Mutex6unlockEv __ZN3WTF5Mutex7tryLockEv __ZN3WTF5MutexC1Ev __ZN3WTF5MutexD1Ev +__ZN3WTF5yieldEv __ZN3WTF6strtodEPKcPPc __ZN3WTF7CString11mutableDataEv __ZN3WTF7CString16newUninitializedEmRPc diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def index a6ff1c2..a478725 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def @@ -330,6 +330,7 @@ EXPORTS ?wait@ThreadCondition@WTF@@QAEXAAVMutex@2@@Z ?waitForThreadCompletion@WTF@@YAHIPAPAX@Z ?writable@PropertyDescriptor@JSC@@QBE_NXZ + ?yield@WTF@@YAXXZ WTFLog WTFLogVerbose WTFReportArgumentAssertionFailure diff --git a/JavaScriptCore/jit/JITPropertyAccess.cpp b/JavaScriptCore/jit/JITPropertyAccess.cpp index 580e73f..10dcd3f 100644 --- a/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -103,10 +103,10 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) emitJumpSlowCaseIfNotJSCell(regT0, base); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT2); addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); + loadPtr(BaseIndex(regT2, regT1, ScalePtr), regT0); addSlowCase(branchTestPtr(Zero, regT0)); emitPutVirtualRegister(dst); @@ -214,22 +214,21 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); - - Jump empty = branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT2); + Jump empty = branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr)); Label storeResult(this); emitGetVirtualRegister(value, regT0); - storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); + storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr)); Jump end = jump(); empty.link(this); - add32(Imm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); - branch32(Below, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this); + add32(Imm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)-OBJECT_OFFSETOF(ArrayStorage, m_vector))); + branch32(Below, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector))).linkTo(storeResult, this); move(regT1, regT0); add32(Imm32(1), regT0); - store32(regT0, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))); + store32(regT0, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector))); jump().linkTo(storeResult, this); end.link(this); @@ -726,9 +725,8 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress) Jump failureCases1 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)); // Checks out okay! - get the length from the storage - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); - load32(Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2); - + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT3); + load32(Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector)), regT2); Jump failureCases2 = branch32(Above, regT2, Imm32(JSImmediate::maxImmediateInt)); emitFastArithIntToImmNoCheck(regT2, regT0); diff --git a/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/JavaScriptCore/jit/JITPropertyAccess32_64.cpp index 6234842..375d3e8 100644 --- a/JavaScriptCore/jit/JITPropertyAccess32_64.cpp +++ b/JavaScriptCore/jit/JITPropertyAccess32_64.cpp @@ -311,11 +311,11 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) emitJumpSlowCaseIfNotJSCell(base, regT1); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT3); addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag - load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload addSlowCase(branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag))); emitStore(dst, regT1, regT0); @@ -364,22 +364,22 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT3); - Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::EmptyValueTag)); + Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::EmptyValueTag)); Label storeResult(this); emitLoad(value, regT1, regT0); - store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); // payload - store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); // tag + store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); // payload + store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); // tag Jump end = jump(); empty.link(this); - add32(Imm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); - branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this); + add32(Imm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)-OBJECT_OFFSETOF(ArrayStorage, m_vector))); + branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector))).linkTo(storeResult, this); add32(Imm32(1), regT2, regT0); - store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))); + store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector))); jump().linkTo(storeResult, this); end.link(this); @@ -731,8 +731,8 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress) Jump failureCases1 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)); // Checks out okay! - get the length from the storage - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); - load32(Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT2); + load32(Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector)), regT2); Jump failureCases2 = branch32(Above, regT2, Imm32(INT_MAX)); move(regT2, regT0); diff --git a/JavaScriptCore/jsc/CMakeLists.txt b/JavaScriptCore/jsc/CMakeLists.txt index 970c20f..756ba92 100644 --- a/JavaScriptCore/jsc/CMakeLists.txt +++ b/JavaScriptCore/jsc/CMakeLists.txt @@ -16,3 +16,4 @@ INCLUDE_DIRECTORIES(./ ${JavaScriptCore_INCLUDE_DIRECTORIES}) ADD_EXECUTABLE(${JSC_EXECUTABLE_NAME} ${JSC_HEADERS} ${JSC_SOURCES}) TARGET_LINK_LIBRARIES(${JSC_EXECUTABLE_NAME} ${JSC_LIBRARIES}) ADD_TARGET_PROPERTIES(${JSC_EXECUTABLE_NAME} LINK_FLAGS ${JSC_LINK_FLAGS}) +SET_TARGET_PROPERTIES(${JSC_EXECUTABLE_NAME} PROPERTIES VERSION ${PROJECT_VERSION}) diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp index e79c46d..fa6eb99 100644 --- a/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -424,13 +424,17 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec) result = jsUndefined(); } else { result = thisObj->get(exec, 0); - for (unsigned k = 1; k < length; k++) { - if (JSValue obj = getProperty(exec, thisObj, k)) - thisObj->put(exec, k - 1, obj); - else - thisObj->deleteProperty(exec, k - 1); + if (isJSArray(&exec->globalData(), thisObj)) + ((JSArray *)thisObj)->shiftCount(exec, 1); + else { + for (unsigned k = 1; k < length; k++) { + if (JSValue obj = getProperty(exec, thisObj, k)) + thisObj->put(exec, k - 1, obj); + else + thisObj->deleteProperty(exec, k - 1); + } + thisObj->deleteProperty(exec, length - 1); } - thisObj->deleteProperty(exec, length - 1); putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - 1)); } return JSValue::encode(result); @@ -578,20 +582,28 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0); if (additionalArgs != deleteCount) { if (additionalArgs < deleteCount) { - for (unsigned k = begin; k < length - deleteCount; ++k) { - if (JSValue v = getProperty(exec, thisObj, k + deleteCount)) - thisObj->put(exec, k + additionalArgs, v); - else - thisObj->deleteProperty(exec, k + additionalArgs); + if ((!begin) && (isJSArray(&exec->globalData(), thisObj))) + ((JSArray *)thisObj)->shiftCount(exec, deleteCount - additionalArgs); + else { + for (unsigned k = begin; k < length - deleteCount; ++k) { + if (JSValue v = getProperty(exec, thisObj, k + deleteCount)) + thisObj->put(exec, k + additionalArgs, v); + else + thisObj->deleteProperty(exec, k + additionalArgs); + } + for (unsigned k = length; k > length - deleteCount + additionalArgs; --k) + thisObj->deleteProperty(exec, k - 1); } - for (unsigned k = length; k > length - deleteCount + additionalArgs; --k) - thisObj->deleteProperty(exec, k - 1); } else { - for (unsigned k = length - deleteCount; k > begin; --k) { - if (JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1)) - thisObj->put(exec, k + additionalArgs - 1, obj); - else - thisObj->deleteProperty(exec, k + additionalArgs - 1); + if ((!begin) && (isJSArray(&exec->globalData(), thisObj))) + ((JSArray *)thisObj)->unshiftCount(exec, additionalArgs - deleteCount); + else { + for (unsigned k = length - deleteCount; k > begin; --k) { + if (JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1)) + thisObj->put(exec, k + additionalArgs - 1, obj); + else + thisObj->deleteProperty(exec, k + additionalArgs - 1); + } } } } @@ -610,12 +622,16 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec) // 15.4.4.13 unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); unsigned nrArgs = exec->argumentCount(); - if (nrArgs) { - for (unsigned k = length; k > 0; --k) { - if (JSValue v = getProperty(exec, thisObj, k - 1)) - thisObj->put(exec, k + nrArgs - 1, v); - else - thisObj->deleteProperty(exec, k + nrArgs - 1); + if ((nrArgs) && (length)) { + if (isJSArray(&exec->globalData(), thisObj)) + ((JSArray *)thisObj)->unshiftCount(exec, nrArgs); + else { + for (unsigned k = length; k > 0; --k) { + if (JSValue v = getProperty(exec, thisObj, k - 1)) + thisObj->put(exec, k + nrArgs - 1, v); + else + thisObj->deleteProperty(exec, k + nrArgs - 1); + } } } for (unsigned k = 0; k < nrArgs; ++k) diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h index f5bf113..1dc9445 100644 --- a/JavaScriptCore/runtime/Collector.h +++ b/JavaScriptCore/runtime/Collector.h @@ -185,16 +185,6 @@ namespace JSC { }; // tunable parameters - template<size_t bytesPerWord> struct CellSize; - - // cell size needs to be a power of two for certain optimizations in collector.cpp -#if USE(JSVALUE32) - template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 32; }; -#else - template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 64; }; -#endif - template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; }; - #if OS(WINCE) || OS(SYMBIAN) const size_t BLOCK_SIZE = 64 * 1024; // 64k #else @@ -204,7 +194,7 @@ namespace JSC { // derived constants const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1; const size_t BLOCK_MASK = ~BLOCK_OFFSET_MASK; - const size_t MINIMUM_CELL_SIZE = CellSize<sizeof(void*)>::m_value; + const size_t MINIMUM_CELL_SIZE = 64; const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? sizeof(double) : 0); const size_t CELL_SIZE = CELL_ARRAY_LENGTH * sizeof(double); const size_t SMALL_CELL_SIZE = CELL_SIZE / 2; diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp index 56603a3..99e1a10 100644 --- a/JavaScriptCore/runtime/JSArray.cpp +++ b/JavaScriptCore/runtime/JSArray.cpp @@ -78,6 +78,14 @@ ASSERT_CLASS_FITS_IN_CELL(JSArray); // 0xFFFFFFFF is a bit weird -- is not an array index even though it's an integer. #define MAX_ARRAY_INDEX 0xFFFFFFFEU +// The value BASE_VECTOR_LEN is the maximum number of vector elements we'll allocate +// for an array that was created with a sepcified length (e.g. a = new Array(123)) +#define BASE_VECTOR_LEN 4U + +// The upper bound to the size we'll grow a zero length array when the first element +// is added. +#define FIRST_VECTOR_GROW 4U + // Our policy for when to use a vector and when to use a sparse map. // For all array indices under MIN_SPARSE_ARRAY_INDEX, we always use a vector. // When indices greater than MIN_SPARSE_ARRAY_INDEX are involved, we use a vector @@ -86,6 +94,11 @@ static const unsigned minDensityMultiplier = 8; const ClassInfo JSArray::info = {"Array", 0, 0, 0}; +// We keep track of the size of the last array after it was grown. We use this +// as a simple heuristic for as the value to grow the next array from size 0. +// This value is capped by the constant FIRST_VECTOR_GROW defined above. +static unsigned lastArraySize = 0; + static inline size_t storageSize(unsigned vectorLength) { ASSERT(vectorLength <= MAX_STORAGE_VECTOR_LENGTH); @@ -100,21 +113,6 @@ static inline size_t storageSize(unsigned vectorLength) return size; } -static inline unsigned increasedVectorLength(unsigned newLength) -{ - ASSERT(newLength <= MAX_STORAGE_VECTOR_LENGTH); - - // Mathematically equivalent to: - // increasedLength = (newLength * 3 + 1) / 2; - // or: - // increasedLength = (unsigned)ceil(newLength * 1.5)); - // This form is not prone to internal overflow. - unsigned increasedLength = newLength + (newLength >> 1) + (newLength & 1); - ASSERT(increasedLength >= newLength); - - return min(increasedLength, MAX_STORAGE_VECTOR_LENGTH); -} - static inline bool isDenseEnoughForVector(unsigned length, unsigned numValues) { return length / minDensityMultiplier <= numValues; @@ -133,7 +131,9 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure) { unsigned initialCapacity = 0; - m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity))); + ArrayStorage* storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity))); + m_indexBias = 0; + setArrayStorage(storage); m_vectorLength = initialCapacity; checkConsistency(); @@ -146,33 +146,36 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength, if (creationMode == CreateCompact) initialCapacity = initialLength; else - initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX); - - m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); + initialCapacity = min(BASE_VECTOR_LEN, MIN_SPARSE_ARRAY_INDEX); + + ArrayStorage* storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); + storage->m_length = initialLength; + m_indexBias = 0; m_vectorLength = initialCapacity; - m_storage->m_sparseValueMap = 0; - m_storage->subclassData = 0; - m_storage->reportedMapCapacity = 0; + setArrayStorage(storage); + storage->m_sparseValueMap = 0; + storage->subclassData = 0; + storage->reportedMapCapacity = 0; if (creationMode == CreateCompact) { #if CHECK_ARRAY_CONSISTENCY - m_storage->m_inCompactInitialization = !!initialCapacity; + storage->m_inCompactInitialization = !!initialCapacity; #endif - m_storage->m_length = 0; - m_storage->m_numValuesInVector = initialCapacity; + storage->m_length = 0; + storage->m_numValuesInVector = initialCapacity; } else { #if CHECK_ARRAY_CONSISTENCY - m_storage->m_inCompactInitialization = false; + storage->m_inCompactInitialization = false; #endif - m_storage->m_length = initialLength; - m_storage->m_numValuesInVector = 0; - JSValue* vector = m_storage->m_vector; + storage->m_length = initialLength; + storage->m_numValuesInVector = 0; + JSValue* vector = m_vector; for (size_t i = 0; i < initialCapacity; ++i) vector[i] = JSValue(); } checkConsistency(); - + Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue)); } @@ -181,21 +184,24 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list) { unsigned initialCapacity = list.size(); - m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); - m_storage->m_length = initialCapacity; + ArrayStorage* storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); + m_indexBias = 0; + storage->m_length = initialCapacity; m_vectorLength = initialCapacity; - m_storage->m_numValuesInVector = initialCapacity; - m_storage->m_sparseValueMap = 0; - m_storage->subclassData = 0; - m_storage->reportedMapCapacity = 0; + storage->m_numValuesInVector = initialCapacity; + storage->m_sparseValueMap = 0; + storage->subclassData = 0; + storage->reportedMapCapacity = 0; #if CHECK_ARRAY_CONSISTENCY - m_storage->m_inCompactInitialization = false; + storage->m_inCompactInitialization = false; #endif + setArrayStorage(storage); size_t i = 0; + JSValue* vector = m_vector; ArgList::const_iterator end = list.end(); for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i) - m_storage->m_vector[i] = *it; + vector[i] = *it; checkConsistency(); @@ -207,14 +213,16 @@ JSArray::~JSArray() ASSERT(vptr() == JSGlobalData::jsArrayVPtr); checkConsistency(DestructorConsistencyCheck); - delete m_storage->m_sparseValueMap; - fastFree(m_storage); + ArrayStorage* storage = arrayStorage(); + delete storage->m_sparseValueMap; + char* realStorage = reinterpret_cast<char*>(storage) - (m_indexBias * sizeof(JSValue)); + fastFree(realStorage); } bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot) { - ArrayStorage* storage = m_storage; - + ArrayStorage* storage = arrayStorage(); + if (i >= storage->m_length) { if (i > MAX_ARRAY_INDEX) return getOwnPropertySlot(exec, Identifier::from(exec, i), slot); @@ -222,7 +230,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot } if (i < m_vectorLength) { - JSValue& valueSlot = storage->m_vector[i]; + JSValue& valueSlot = m_vector[i]; if (valueSlot) { slot.setValueSlot(&valueSlot); return true; @@ -261,19 +269,21 @@ bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& proper descriptor.setDescriptor(jsNumber(exec, length()), DontDelete | DontEnum); return true; } + + ArrayStorage* storage = arrayStorage(); bool isArrayIndex; unsigned i = propertyName.toArrayIndex(&isArrayIndex); if (isArrayIndex) { - if (i >= m_storage->m_length) + if (i >= storage->m_length) return false; if (i < m_vectorLength) { - JSValue& value = m_storage->m_vector[i]; + JSValue& value = m_vector[i]; if (value) { descriptor.setDescriptor(value, 0); return true; } - } else if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) { + } else if (SparseArrayValueMap* map = storage->m_sparseValueMap) { if (i >= MIN_SPARSE_ARRAY_INDEX) { SparseArrayValueMap::iterator it = map->find(i); if (it != map->end()) { @@ -313,21 +323,23 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value) { checkConsistency(); - unsigned length = m_storage->m_length; + ArrayStorage* storage = arrayStorage(); + + unsigned length = storage->m_length; if (i >= length && i <= MAX_ARRAY_INDEX) { length = i + 1; - m_storage->m_length = length; + storage->m_length = length; } if (i < m_vectorLength) { - JSValue& valueSlot = m_storage->m_vector[i]; + JSValue& valueSlot = m_vector[i]; if (valueSlot) { valueSlot = value; checkConsistency(); return; } valueSlot = value; - ++m_storage->m_numValuesInVector; + ++storage->m_numValuesInVector; checkConsistency(); return; } @@ -337,7 +349,8 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value) NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue value) { - ArrayStorage* storage = m_storage; + ArrayStorage* storage = arrayStorage(); + SparseArrayValueMap* map = storage->m_sparseValueMap; if (i >= MIN_SPARSE_ARRAY_INDEX) { @@ -374,9 +387,8 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu // Fast case is when there is no sparse map, so we can increase the vector size without moving values from it. if (!map || map->isEmpty()) { if (increaseVectorLength(i + 1)) { - storage = m_storage; - storage->m_vector[i] = value; - ++storage->m_numValuesInVector; + m_vector[i] = value; + ++arrayStorage()->m_numValuesInVector; checkConsistency(); } else throwOutOfMemoryError(exec); @@ -385,7 +397,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu // Decide how many values it would be best to move from the map. unsigned newNumValuesInVector = storage->m_numValuesInVector + 1; - unsigned newVectorLength = increasedVectorLength(i + 1); + unsigned newVectorLength = getNewVectorLength(i + 1); for (unsigned j = max(m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) newNumValuesInVector += map->contains(j); if (i >= MIN_SPARSE_ARRAY_INDEX) @@ -394,7 +406,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu unsigned proposedNewNumValuesInVector = newNumValuesInVector; // If newVectorLength is already the maximum - MAX_STORAGE_VECTOR_LENGTH - then do not attempt to grow any further. while (newVectorLength < MAX_STORAGE_VECTOR_LENGTH) { - unsigned proposedNewVectorLength = increasedVectorLength(newVectorLength + 1); + unsigned proposedNewVectorLength = getNewVectorLength(newVectorLength + 1); for (unsigned j = max(newVectorLength, MIN_SPARSE_ARRAY_INDEX); j < proposedNewVectorLength; ++j) proposedNewNumValuesInVector += map->contains(j); if (!isDenseEnoughForVector(proposedNewVectorLength, proposedNewNumValuesInVector)) @@ -404,31 +416,37 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu } } - if (!tryFastRealloc(storage, storageSize(newVectorLength)).getValue(storage)) { + int baseBias = m_indexBias * sizeof(JSValue); + char* baseStorage = reinterpret_cast<char*>(storage - baseBias); + + if (!tryFastRealloc(baseStorage, storageSize(newVectorLength + m_indexBias)).getValue(baseStorage)) { throwOutOfMemoryError(exec); return; } + storage = reinterpret_cast<ArrayStorage*>(baseStorage + baseBias); + setArrayStorage(storage); + unsigned vectorLength = m_vectorLength; if (newNumValuesInVector == storage->m_numValuesInVector + 1) { for (unsigned j = vectorLength; j < newVectorLength; ++j) - storage->m_vector[j] = JSValue(); + m_vector[j] = JSValue(); if (i > MIN_SPARSE_ARRAY_INDEX) map->remove(i); } else { for (unsigned j = vectorLength; j < max(vectorLength, MIN_SPARSE_ARRAY_INDEX); ++j) - storage->m_vector[j] = JSValue(); + m_vector[j] = JSValue(); for (unsigned j = max(vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) - storage->m_vector[j] = map->take(j); + m_vector[j] = map->take(j); } - storage->m_vector[i] = value; + ASSERT(i < newVectorLength); m_vectorLength = newVectorLength; storage->m_numValuesInVector = newNumValuesInVector; - m_storage = storage; + m_vector[i] = value; checkConsistency(); @@ -452,10 +470,10 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i) { checkConsistency(); - ArrayStorage* storage = m_storage; - + ArrayStorage* storage = arrayStorage(); + if (i < m_vectorLength) { - JSValue& valueSlot = storage->m_vector[i]; + JSValue& valueSlot = m_vector[i]; if (!valueSlot) { checkConsistency(); return false; @@ -491,11 +509,11 @@ void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNa // is incredibly inefficient for large arrays. We need a different approach, // which almost certainly means a different structure for PropertyNameArray. - ArrayStorage* storage = m_storage; - + ArrayStorage* storage = arrayStorage(); + unsigned usedVectorLength = min(storage->m_length, m_vectorLength); for (unsigned i = 0; i < usedVectorLength; ++i) { - if (storage->m_vector[i]) + if (m_vector[i]) propertyNames.add(Identifier::from(exec, i)); } @@ -511,32 +529,101 @@ void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNa JSObject::getOwnPropertyNames(exec, propertyNames, mode); } +ALWAYS_INLINE unsigned JSArray::getNewVectorLength(unsigned desiredLength) +{ + ASSERT(desiredLength <= MAX_STORAGE_VECTOR_LENGTH); + + unsigned increasedLength; + unsigned length = arrayStorage()->m_length; + + if (desiredLength < length) + increasedLength = length; + else if (!m_vectorLength) + increasedLength = max(desiredLength, lastArraySize); + else { + // Mathematically equivalent to: + // increasedLength = (newLength * 3 + 1) / 2; + // or: + // increasedLength = (unsigned)ceil(newLength * 1.5)); + // This form is not prone to internal overflow. + increasedLength = desiredLength + (desiredLength >> 1) + (desiredLength & 1); + } + + ASSERT(increasedLength >= desiredLength); + + lastArraySize = min(increasedLength, FIRST_VECTOR_GROW); + + return min(increasedLength, MAX_STORAGE_VECTOR_LENGTH); +} + bool JSArray::increaseVectorLength(unsigned newLength) { // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map // to the vector. Callers have to account for that, because they can do it more efficiently. - ArrayStorage* storage = m_storage; + ArrayStorage* storage = arrayStorage(); unsigned vectorLength = m_vectorLength; ASSERT(newLength > vectorLength); ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX); - unsigned newVectorLength = increasedVectorLength(newLength); + unsigned newVectorLength = getNewVectorLength(newLength); + int baseBias = m_indexBias * sizeof(JSValue); + char* baseStorage = reinterpret_cast<char*>(storage) - baseBias; - if (!tryFastRealloc(storage, storageSize(newVectorLength)).getValue(storage)) + if (!tryFastRealloc(baseStorage, storageSize(newVectorLength + m_indexBias)).getValue(baseStorage)) return false; + + storage = reinterpret_cast<ArrayStorage*>(baseStorage + baseBias); + setArrayStorage(storage); + + JSValue* vector = m_vector; + for (unsigned i = vectorLength; i < newVectorLength; ++i) + vector[i] = JSValue(); m_vectorLength = newVectorLength; + + Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); - for (unsigned i = vectorLength; i < newVectorLength; ++i) - storage->m_vector[i] = JSValue(); + return true; +} - m_storage = storage; +bool JSArray::increaseVectorPrefixLength(unsigned newLength) +{ + // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map + // to the vector. Callers have to account for that, because they can do it more efficiently. + + ArrayStorage* storage = arrayStorage(); + ArrayStorage* newStorage; + + unsigned vectorLength = m_vectorLength; + ASSERT(newLength > vectorLength); + ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX); + unsigned newVectorLength = getNewVectorLength(newLength); + char* baseStorage = reinterpret_cast<char*>(storage) - (m_indexBias * sizeof(JSValue)); + + char* newBaseStorage = reinterpret_cast<char*>(fastMalloc(storageSize(newVectorLength + m_indexBias))); + if (!newBaseStorage) + return false; + + m_indexBias += newVectorLength - newLength; + int newStorageOffset = m_indexBias * sizeof(JSValue); + + newStorage = reinterpret_cast<ArrayStorage*>(newBaseStorage + newStorageOffset); + + memcpy(newStorage, storage, storageSize(0)); + memcpy(&newStorage->m_vector[newLength - m_vectorLength], &storage->m_vector[0], storage->m_length * sizeof(JSValue)); + + m_vectorLength = newLength; + + fastFree(baseStorage); + setArrayStorage(newStorage); + Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); - + return true; } + void JSArray::setLength(unsigned newLength) { @@ -547,14 +634,14 @@ void JSArray::setLength(unsigned newLength) m_storage->m_inCompactInitialization = false; #endif - ArrayStorage* storage = m_storage; - - unsigned length = m_storage->m_length; + ArrayStorage* storage = arrayStorage(); + + unsigned length = storage->m_length; if (newLength < length) { unsigned usedVectorLength = min(length, m_vectorLength); for (unsigned i = newLength; i < usedVectorLength; ++i) { - JSValue& valueSlot = storage->m_vector[i]; + JSValue& valueSlot = m_vector[i]; bool hadValue = valueSlot; valueSlot = JSValue(); storage->m_numValuesInVector -= hadValue; @@ -574,7 +661,7 @@ void JSArray::setLength(unsigned newLength) } } - m_storage->m_length = newLength; + storage->m_length = newLength; checkConsistency(); } @@ -583,7 +670,9 @@ JSValue JSArray::pop() { checkConsistency(); - unsigned length = m_storage->m_length; + ArrayStorage* storage = arrayStorage(); + + unsigned length = storage->m_length; if (!length) return jsUndefined(); @@ -592,29 +681,29 @@ JSValue JSArray::pop() JSValue result; if (length < m_vectorLength) { - JSValue& valueSlot = m_storage->m_vector[length]; + JSValue& valueSlot = m_vector[length]; if (valueSlot) { - --m_storage->m_numValuesInVector; + --storage->m_numValuesInVector; result = valueSlot; valueSlot = JSValue(); } else result = jsUndefined(); } else { result = jsUndefined(); - if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) { + if (SparseArrayValueMap* map = storage->m_sparseValueMap) { SparseArrayValueMap::iterator it = map->find(length); if (it != map->end()) { result = it->second; map->remove(it); if (map->isEmpty()) { delete map; - m_storage->m_sparseValueMap = 0; + storage->m_sparseValueMap = 0; } } } } - m_storage->m_length = length; + storage->m_length = length; checkConsistency(); @@ -624,22 +713,25 @@ JSValue JSArray::pop() void JSArray::push(ExecState* exec, JSValue value) { checkConsistency(); + + ArrayStorage* storage = arrayStorage(); - if (m_storage->m_length < m_vectorLength) { - m_storage->m_vector[m_storage->m_length] = value; - ++m_storage->m_numValuesInVector; - ++m_storage->m_length; + if (storage->m_length < m_vectorLength) { + m_vector[storage->m_length] = value; + ++storage->m_numValuesInVector; + ++storage->m_length; checkConsistency(); return; } - if (m_storage->m_length < MIN_SPARSE_ARRAY_INDEX) { - SparseArrayValueMap* map = m_storage->m_sparseValueMap; + if (storage->m_length < MIN_SPARSE_ARRAY_INDEX) { + SparseArrayValueMap* map = storage->m_sparseValueMap; if (!map || map->isEmpty()) { - if (increaseVectorLength(m_storage->m_length + 1)) { - m_storage->m_vector[m_storage->m_length] = value; - ++m_storage->m_numValuesInVector; - ++m_storage->m_length; + if (increaseVectorLength(storage->m_length + 1)) { + storage = arrayStorage(); + m_vector[storage->m_length] = value; + ++storage->m_numValuesInVector; + ++storage->m_length; checkConsistency(); return; } @@ -649,7 +741,98 @@ void JSArray::push(ExecState* exec, JSValue value) } } - putSlowCase(exec, m_storage->m_length++, value); + putSlowCase(exec, storage->m_length++, value); +} + +void JSArray::shiftCount(ExecState* exec, int count) +{ + ASSERT(count > 0); + + ArrayStorage* storage = arrayStorage(); + + unsigned oldLength = storage->m_length; + + if (!oldLength) + return; + + if (oldLength != storage->m_numValuesInVector) { + // If m_length and m_numValuesInVector aren't the same, we have a sparse vector + // which means we need to go through each entry looking for the the "empty" + // slots and then fill them with possible properties. See ECMA spec. + // 15.4.4.9 steps 11 through 13. + for (unsigned i = count; i < oldLength; ++i) { + if ((i >= m_vectorLength) || (!m_vector[i])) { + PropertySlot slot(this); + JSValue p = prototype(); + if ((!p.isNull()) && (asObject(p)->getPropertySlot(exec, i, slot))) + put(exec, i, slot.getValue(exec, i)); + } + } + + storage = arrayStorage(); // The put() above could have grown the vector and realloc'ed storage. + + // Need to decrement numValuesInvector based on number of real entries + for (unsigned i = 0; i < (unsigned)count; ++i) + if ((i < m_vectorLength) && (m_vector[i])) + --storage->m_numValuesInVector; + } else + storage->m_numValuesInVector -= count; + + storage->m_length -= count; + + if (m_vectorLength) { + count = min(m_vectorLength, (unsigned)count); + + m_vectorLength -= count; + + if (m_vectorLength) { + char* newBaseStorage = reinterpret_cast<char*>(storage) + count * sizeof(JSValue); + memmove(newBaseStorage, storage, storageSize(0)); + storage = reinterpret_cast<ArrayStorage*>(newBaseStorage); + + m_indexBias += count; + setArrayStorage(storage); + } + } +} + +void JSArray::unshiftCount(ExecState* exec, int count) +{ + ArrayStorage* storage = arrayStorage(); + + ASSERT(m_indexBias >= 0); + ASSERT(count >= 0); + + unsigned length = storage->m_length; + + if (length != storage->m_numValuesInVector) { + // If m_length and m_numValuesInVector aren't the same, we have a sparse vector + // which means we need to go through each entry looking for the the "empty" + // slots and then fill them with possible properties. See ECMA spec. + // 15.4.4.13 steps 8 through 10. + for (unsigned i = 0; i < length; ++i) { + if ((i >= m_vectorLength) || (!m_vector[i])) { + PropertySlot slot(this); + JSValue p = prototype(); + if ((!p.isNull()) && (asObject(p)->getPropertySlot(exec, i, slot))) + put(exec, i, slot.getValue(exec, i)); + } + } + } + + storage = arrayStorage(); // The put() above could have grown the vector and realloc'ed storage. + + if (m_indexBias >= count) { + m_indexBias -= count; + char* newBaseStorage = reinterpret_cast<char*>(storage) - count * sizeof(JSValue); + memmove(newBaseStorage, storage, storageSize(0)); + storage = reinterpret_cast<ArrayStorage*>(newBaseStorage); + setArrayStorage(storage); + m_vectorLength += count; + } else if ((!m_indexBias) && (!increaseVectorPrefixLength(m_vectorLength + count))) { + throwOutOfMemoryError(exec); + return; + } } void JSArray::markChildren(MarkStack& markStack) @@ -675,8 +858,10 @@ static int compareByStringPairForQSort(const void* a, const void* b) void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData) { + ArrayStorage* storage = arrayStorage(); + unsigned lengthNotIncludingUndefined = compactForSorting(); - if (m_storage->m_sparseValueMap) { + if (storage->m_sparseValueMap) { throwOutOfMemoryError(exec); return; } @@ -685,9 +870,9 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal return; bool allValuesAreNumbers = true; - size_t size = m_storage->m_numValuesInVector; + size_t size = storage->m_numValuesInVector; for (size_t i = 0; i < size; ++i) { - if (!m_storage->m_vector[i].isNumber()) { + if (!m_vector[i].isNumber()) { allValuesAreNumbers = false; break; } @@ -699,15 +884,17 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal // For numeric comparison, which is fast, qsort is faster than mergesort. We // also don't require mergesort's stability, since there's no user visible // side-effect from swapping the order of equal primitive values. - qsort(m_storage->m_vector, size, sizeof(JSValue), compareNumbersForQSort); + qsort(m_vector, size, sizeof(JSValue), compareNumbersForQSort); checkConsistency(SortConsistencyCheck); } void JSArray::sort(ExecState* exec) { + ArrayStorage* storage = arrayStorage(); + unsigned lengthNotIncludingUndefined = compactForSorting(); - if (m_storage->m_sparseValueMap) { + if (storage->m_sparseValueMap) { throwOutOfMemoryError(exec); return; } @@ -727,7 +914,7 @@ void JSArray::sort(ExecState* exec) } for (size_t i = 0; i < lengthNotIncludingUndefined; i++) { - JSValue value = m_storage->m_vector[i]; + JSValue value = m_vector[i]; ASSERT(!value.isUndefined()); values[i].first = value; } @@ -759,7 +946,7 @@ void JSArray::sort(ExecState* exec) // modifying the vector incorrectly. for (size_t i = 0; i < lengthNotIncludingUndefined; i++) - m_storage->m_vector[i] = values[i].first; + m_vector[i] = values[i].first; checkConsistency(SortConsistencyCheck); } @@ -846,18 +1033,20 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, { checkConsistency(); + ArrayStorage* storage = arrayStorage(); + // FIXME: This ignores exceptions raised in the compare function or in toNumber. // The maximum tree depth is compiled in - but the caller is clearly up to no good // if a larger array is passed. - ASSERT(m_storage->m_length <= static_cast<unsigned>(std::numeric_limits<int>::max())); - if (m_storage->m_length > static_cast<unsigned>(std::numeric_limits<int>::max())) + ASSERT(storage->m_length <= static_cast<unsigned>(std::numeric_limits<int>::max())); + if (storage->m_length > static_cast<unsigned>(std::numeric_limits<int>::max())) return; - if (!m_storage->m_length) + if (!storage->m_length) return; - unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength); + unsigned usedVectorLength = min(storage->m_length, m_vectorLength); AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items tree.abstractor().m_exec = exec; @@ -865,7 +1054,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, tree.abstractor().m_compareCallType = callType; tree.abstractor().m_compareCallData = &callData; tree.abstractor().m_globalThisValue = exec->globalThisValue(); - tree.abstractor().m_nodes.resize(usedVectorLength + (m_storage->m_sparseValueMap ? m_storage->m_sparseValueMap->size() : 0)); + tree.abstractor().m_nodes.resize(usedVectorLength + (storage->m_sparseValueMap ? storage->m_sparseValueMap->size() : 0)); if (callType == CallTypeJS) tree.abstractor().m_cachedCall = adoptPtr(new CachedCall(exec, asFunction(compareFunction), 2, exec->exceptionSlot())); @@ -883,14 +1072,14 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree. for (; numDefined < usedVectorLength; ++numDefined) { - JSValue v = m_storage->m_vector[numDefined]; + JSValue v = m_vector[numDefined]; if (!v || v.isUndefined()) break; tree.abstractor().m_nodes[numDefined].value = v; tree.insert(numDefined); } for (unsigned i = numDefined; i < usedVectorLength; ++i) { - JSValue v = m_storage->m_vector[i]; + JSValue v = m_vector[i]; if (v) { if (v.isUndefined()) ++numUndefined; @@ -904,7 +1093,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, unsigned newUsedVectorLength = numDefined + numUndefined; - if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) { + if (SparseArrayValueMap* map = storage->m_sparseValueMap) { newUsedVectorLength += map->size(); if (newUsedVectorLength > m_vectorLength) { // Check that it is possible to allocate an array large enough to hold all the entries. @@ -913,6 +1102,8 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, return; } } + + storage = arrayStorage(); SparseArrayValueMap::iterator end = map->end(); for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) { @@ -922,7 +1113,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, } delete map; - m_storage->m_sparseValueMap = 0; + storage->m_sparseValueMap = 0; } ASSERT(tree.abstractor().m_nodes.size() >= numDefined); @@ -934,27 +1125,29 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter; iter.start_iter_least(tree); for (unsigned i = 0; i < numDefined; ++i) { - m_storage->m_vector[i] = tree.abstractor().m_nodes[*iter].value; + m_vector[i] = tree.abstractor().m_nodes[*iter].value; ++iter; } // Put undefined values back in. for (unsigned i = numDefined; i < newUsedVectorLength; ++i) - m_storage->m_vector[i] = jsUndefined(); + m_vector[i] = jsUndefined(); // Ensure that unused values in the vector are zeroed out. for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) - m_storage->m_vector[i] = JSValue(); + m_vector[i] = JSValue(); - m_storage->m_numValuesInVector = newUsedVectorLength; + storage->m_numValuesInVector = newUsedVectorLength; checkConsistency(SortConsistencyCheck); } void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) { - JSValue* vector = m_storage->m_vector; - unsigned vectorEnd = min(m_storage->m_length, m_vectorLength); + ArrayStorage* storage = arrayStorage(); + + JSValue* vector = storage->m_vector; + unsigned vectorEnd = min(storage->m_length, m_vectorLength); unsigned i = 0; for (; i < vectorEnd; ++i) { JSValue& v = vector[i]; @@ -963,15 +1156,15 @@ void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) args.append(v); } - for (; i < m_storage->m_length; ++i) + for (; i < storage->m_length; ++i) args.append(get(exec, i)); } void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize) { - ASSERT(m_storage->m_length >= maxSize); + ASSERT(arrayStorage()->m_length >= maxSize); UNUSED_PARAM(maxSize); - JSValue* vector = m_storage->m_vector; + JSValue* vector = m_vector; unsigned vectorEnd = min(maxSize, m_vectorLength); unsigned i = 0; for (; i < vectorEnd; ++i) { @@ -989,25 +1182,25 @@ unsigned JSArray::compactForSorting() { checkConsistency(); - ArrayStorage* storage = m_storage; + ArrayStorage* storage = arrayStorage(); - unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength); + unsigned usedVectorLength = min(storage->m_length, m_vectorLength); unsigned numDefined = 0; unsigned numUndefined = 0; for (; numDefined < usedVectorLength; ++numDefined) { - JSValue v = storage->m_vector[numDefined]; + JSValue v = m_vector[numDefined]; if (!v || v.isUndefined()) break; } for (unsigned i = numDefined; i < usedVectorLength; ++i) { - JSValue v = storage->m_vector[i]; + JSValue v = m_vector[i]; if (v) { if (v.isUndefined()) ++numUndefined; else - storage->m_vector[numDefined++] = v; + m_vector[numDefined++] = v; } } @@ -1020,21 +1213,22 @@ unsigned JSArray::compactForSorting() // exception is thrown by caller. if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) return 0; - storage = m_storage; + + storage = arrayStorage(); } SparseArrayValueMap::iterator end = map->end(); for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) - storage->m_vector[numDefined++] = it->second; + m_vector[numDefined++] = it->second; delete map; storage->m_sparseValueMap = 0; } for (unsigned i = numDefined; i < newUsedVectorLength; ++i) - storage->m_vector[i] = jsUndefined(); + m_vector[i] = jsUndefined(); for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) - storage->m_vector[i] = JSValue(); + m_vector[i] = JSValue(); storage->m_numValuesInVector = newUsedVectorLength; @@ -1045,42 +1239,44 @@ unsigned JSArray::compactForSorting() void* JSArray::subclassData() const { - return m_storage->subclassData; + return arrayStorage()->subclassData; } void JSArray::setSubclassData(void* d) { - m_storage->subclassData = d; + arrayStorage()->subclassData = d; } #if CHECK_ARRAY_CONSISTENCY void JSArray::checkConsistency(ConsistencyCheckType type) { - ASSERT(m_storage); + ArrayStorage* storage = arrayStorage(); + + ASSERT(storage); if (type == SortConsistencyCheck) - ASSERT(!m_storage->m_sparseValueMap); + ASSERT(!storage->m_sparseValueMap); unsigned numValuesInVector = 0; for (unsigned i = 0; i < m_vectorLength; ++i) { - if (JSValue value = m_storage->m_vector[i]) { - ASSERT(i < m_storage->m_length); + if (JSValue value = m_vector[i]) { + ASSERT(i < storage->m_length); if (type != DestructorConsistencyCheck) value.isUndefined(); // Likely to crash if the object was deallocated. ++numValuesInVector; } else { if (type == SortConsistencyCheck) - ASSERT(i >= m_storage->m_numValuesInVector); + ASSERT(i >= storage->m_numValuesInVector); } } - ASSERT(numValuesInVector == m_storage->m_numValuesInVector); - ASSERT(numValuesInVector <= m_storage->m_length); + ASSERT(numValuesInVector == storage->m_numValuesInVector); + ASSERT(numValuesInVector <= storage->m_length); - if (m_storage->m_sparseValueMap) { - SparseArrayValueMap::iterator end = m_storage->m_sparseValueMap->end(); - for (SparseArrayValueMap::iterator it = m_storage->m_sparseValueMap->begin(); it != end; ++it) { + if (storage->m_sparseValueMap) { + SparseArrayValueMap::iterator end = storage->m_sparseValueMap->end(); + for (SparseArrayValueMap::iterator it = storage->m_sparseValueMap->begin(); it != end; ++it) { unsigned index = it->first; - ASSERT(index < m_storage->m_length); + ASSERT(index < storage->m_length); ASSERT(index >= m_vectorLength); ASSERT(index <= MAX_ARRAY_INDEX); ASSERT(it->second); diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h index b6dd7cc..a7ce328 100644 --- a/JavaScriptCore/runtime/JSArray.h +++ b/JavaScriptCore/runtime/JSArray.h @@ -29,8 +29,13 @@ namespace JSC { typedef HashMap<unsigned, JSValue> SparseArrayValueMap; + // This struct holds the actual data values of an array. A JSArray object points to it's contained ArrayStorage + // struct by pointing to m_vector. To access the contained ArrayStorage struct, use the getStorage() and + // setStorage() methods. It is important to note that there may be space before the ArrayStorage that + // is used to quick unshift / shift operation. The actual allocated pointer is available by using: + // getStorage() - m_indexBias * sizeof(JSValue) struct ArrayStorage { - unsigned m_length; + unsigned m_length; // The "length" property on the array unsigned m_numValuesInVector; SparseArrayValueMap* m_sparseValueMap; void* subclassData; // A JSArray subclass can use this to fill the vector lazily. @@ -67,8 +72,8 @@ namespace JSC { virtual void put(ExecState*, unsigned propertyName, JSValue); // FIXME: Make protected and add setItem. static JS_EXPORTDATA const ClassInfo info; - - unsigned length() const { return m_storage->m_length; } + + unsigned length() const { return arrayStorage()->m_length; } void setLength(unsigned); // OK to use on new arrays, but not if it might be a RegExpMatchArray. void sort(ExecState*); @@ -78,33 +83,39 @@ namespace JSC { void push(ExecState*, JSValue); JSValue pop(); - bool canGetIndex(unsigned i) { return i < m_vectorLength && m_storage->m_vector[i]; } + void shiftCount(ExecState*, int count); + void unshiftCount(ExecState*, int count); + + bool canGetIndex(unsigned i) { return i < m_vectorLength && m_vector[i]; } JSValue getIndex(unsigned i) { ASSERT(canGetIndex(i)); - return m_storage->m_vector[i]; + return m_vector[i]; } bool canSetIndex(unsigned i) { return i < m_vectorLength; } void setIndex(unsigned i, JSValue v) { ASSERT(canSetIndex(i)); - JSValue& x = m_storage->m_vector[i]; + + JSValue& x = m_vector[i]; if (!x) { - ++m_storage->m_numValuesInVector; - if (i >= m_storage->m_length) - m_storage->m_length = i + 1; + ArrayStorage *storage = arrayStorage(); + ++storage->m_numValuesInVector; + if (i >= storage->m_length) + storage->m_length = i + 1; } x = v; } - + void uncheckedSetIndex(unsigned i, JSValue v) { ASSERT(canSetIndex(i)); + ArrayStorage *storage = arrayStorage(); #if CHECK_ARRAY_CONSISTENCY - ASSERT(m_storage->m_inCompactInitialization); + ASSERT(storage->m_inCompactInitialization); #endif - m_storage->m_vector[i] = v; + storage->m_vector[i] = v; } void fillArgList(ExecState*, MarkedArgumentBuffer&); @@ -127,6 +138,16 @@ namespace JSC { void* subclassData() const; void setSubclassData(void*); + + inline ArrayStorage *arrayStorage() const + { + return reinterpret_cast<ArrayStorage*>(reinterpret_cast<char*>(m_vector) - (sizeof(ArrayStorage) - sizeof(JSValue))); + } + + inline void setArrayStorage(ArrayStorage *storage) + { + m_vector = &storage->m_vector[0]; + } private: virtual const ClassInfo* classInfo() const { return &info; } @@ -134,15 +155,18 @@ namespace JSC { bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&); void putSlowCase(ExecState*, unsigned propertyName, JSValue); + unsigned getNewVectorLength(unsigned desiredLength); bool increaseVectorLength(unsigned newLength); + bool increaseVectorPrefixLength(unsigned newLength); unsigned compactForSorting(); enum ConsistencyCheckType { NormalConsistencyCheck, DestructorConsistencyCheck, SortConsistencyCheck }; void checkConsistency(ConsistencyCheckType = NormalConsistencyCheck); - unsigned m_vectorLength; - ArrayStorage* m_storage; + unsigned m_vectorLength; // The valid length of m_vector + int m_indexBias; // The number of JSValue sized blocks before ArrayStorage. + JSValue* m_vector; // Copy of ArrayStorage.m_vector. Used for quick vector access and to materialize ArrayStorage ptr. }; JSArray* asArray(JSValue); @@ -168,7 +192,7 @@ namespace JSC { { JSObject::markChildrenDirect(markStack); - ArrayStorage* storage = m_storage; + ArrayStorage* storage = arrayStorage(); unsigned usedVectorLength = std::min(storage->m_length, m_vectorLength); markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues); diff --git a/JavaScriptCore/wtf/CMakeLists.txt b/JavaScriptCore/wtf/CMakeLists.txt index 1119b3c..5cf108f 100644 --- a/JavaScriptCore/wtf/CMakeLists.txt +++ b/JavaScriptCore/wtf/CMakeLists.txt @@ -42,5 +42,6 @@ TARGET_LINK_LIBRARIES(${WTF_LIBRARY_NAME} ${WTF_LIBRARIES}) ADD_TARGET_PROPERTIES(${WTF_LIBRARY_NAME} LINK_FLAGS ${WTF_LINK_FLAGS}) IF (SHARED_CORE) + SET_TARGET_PROPERTIES(${WTF_LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) INSTALL(TARGETS ${WTF_LIBRARY_NAME} DESTINATION lib) ENDIF () diff --git a/JavaScriptCore/wtf/PageAllocation.cpp b/JavaScriptCore/wtf/PageAllocation.cpp index 58a10f6..4cf2ea9 100644 --- a/JavaScriptCore/wtf/PageAllocation.cpp +++ b/JavaScriptCore/wtf/PageAllocation.cpp @@ -176,7 +176,7 @@ size_t PageAllocation::pagesize() bool PageAllocation::commit(void* start, size_t size, bool writable, bool executable) const { if (m_chunk) { - intptr_t offset = static_cast<intptr_t>(base()) - static_cast<intptr_t>(start); + intptr_t offset = reinterpret_cast<intptr_t>(base()) - reinterpret_cast<intptr_t>(start); m_chunk->Commit(offset, size); } return true; @@ -185,7 +185,7 @@ bool PageAllocation::commit(void* start, size_t size, bool writable, bool execut void PageAllocation::decommit(void* start, size_t size) const { if (m_chunk) { - intptr_t offset = static_cast<intptr_t>(base()) - static_cast<intptr_t>(start); + intptr_t offset = reinterpret_cast<intptr_t>(base()) - reinterpret_cast<intptr_t>(start); m_chunk->Decommit(offset, size); } } @@ -205,7 +205,7 @@ PageAllocation PageAllocation::reserve(size_t size, Usage usage, bool writable, return PageAllocation(fastMalloc(size), size, 0); RChunk* rchunk = new RChunk(); TInt errorCode = rchunk->CreateLocalCode(0, size); - return PageAllocation(rchunk, rchunk->Base(), size); + return PageAllocation(rchunk->Base(), size, rchunk); } void PageAllocation::deallocate() diff --git a/JavaScriptCore/wtf/PageAllocation.h b/JavaScriptCore/wtf/PageAllocation.h index 00b5363..b846482 100644 --- a/JavaScriptCore/wtf/PageAllocation.h +++ b/JavaScriptCore/wtf/PageAllocation.h @@ -67,7 +67,7 @@ public: : m_base(base) , m_size(size) #if OS(SYMBIAN) - , m_chunk(parent.chunk) + , m_chunk(parent.m_chunk) #endif { #if defined(NDEBUG) && !OS(SYMBIAN) diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h index 30948fa..eca4248 100644 --- a/JavaScriptCore/wtf/Platform.h +++ b/JavaScriptCore/wtf/Platform.h @@ -571,9 +571,6 @@ #if PLATFORM(QT) #define WTF_USE_QT4_UNICODE 1 -#if !defined(ENABLE_WIDGETS_10_SUPPORT) -#define ENABLE_WIDGETS_10_SUPPORT 1 -#endif #elif OS(WINCE) #define WTF_USE_WINCE_UNICODE 1 #elif PLATFORM(GTK) @@ -838,10 +835,6 @@ #define ENABLE_DASHBOARD_SUPPORT 0 #endif -#if !defined(ENABLE_WIDGETS_10_SUPPORT) -#define ENABLE_WIDGETS_10_SUPPORT 0 -#endif - #if !defined(ENABLE_INSPECTOR) #define ENABLE_INSPECTOR 1 #endif diff --git a/JavaScriptCore/wtf/Threading.h b/JavaScriptCore/wtf/Threading.h index 415a8fc..044365f 100644 --- a/JavaScriptCore/wtf/Threading.h +++ b/JavaScriptCore/wtf/Threading.h @@ -101,6 +101,7 @@ ThreadIdentifier currentThread(); int waitForThreadCompletion(ThreadIdentifier, void**); void detachThread(ThreadIdentifier); +void yield(); void lockAtomicallyInitializedStaticMutex(); void unlockAtomicallyInitializedStaticMutex(); @@ -112,5 +113,6 @@ using WTF::createThread; using WTF::currentThread; using WTF::detachThread; using WTF::waitForThreadCompletion; +using WTF::yield; #endif // Threading_h diff --git a/JavaScriptCore/wtf/ThreadingPthreads.cpp b/JavaScriptCore/wtf/ThreadingPthreads.cpp index d01cc4a..98286d3 100644 --- a/JavaScriptCore/wtf/ThreadingPthreads.cpp +++ b/JavaScriptCore/wtf/ThreadingPthreads.cpp @@ -44,6 +44,7 @@ #if !COMPILER(MSVC) #include <limits.h> +#include <sched.h> #include <sys/time.h> #endif @@ -221,6 +222,11 @@ void detachThread(ThreadIdentifier threadID) pthread_detach(pthreadHandle); } +void yield() +{ + sched_yield(); +} + ThreadIdentifier currentThread() { ThreadIdentifier id = ThreadIdentifierData::identifier(); diff --git a/JavaScriptCore/wtf/ThreadingWin.cpp b/JavaScriptCore/wtf/ThreadingWin.cpp index c16be5a..a29fbbb 100644 --- a/JavaScriptCore/wtf/ThreadingWin.cpp +++ b/JavaScriptCore/wtf/ThreadingWin.cpp @@ -266,6 +266,11 @@ void detachThread(ThreadIdentifier threadID) clearThreadHandleForIdentifier(threadID); } +void yield() +{ + ::Sleep(1); +} + ThreadIdentifier currentThread() { return static_cast<ThreadIdentifier>(GetCurrentThreadId()); diff --git a/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp b/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp index 981eacb..863ee81 100644 --- a/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp +++ b/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp @@ -167,6 +167,11 @@ ThreadIdentifier currentThread() return establishIdentifierForThread(currentThread); } +void yield() +{ + g_thread_yield(); +} + Mutex::Mutex() : m_mutex(g_mutex_new()) { diff --git a/JavaScriptCore/wtf/qt/ThreadingQt.cpp b/JavaScriptCore/wtf/qt/ThreadingQt.cpp index 7f81646..8041dea 100644 --- a/JavaScriptCore/wtf/qt/ThreadingQt.cpp +++ b/JavaScriptCore/wtf/qt/ThreadingQt.cpp @@ -208,6 +208,11 @@ ThreadIdentifier currentThread() return establishIdentifierForThread(currentThread); } +void yield() +{ + QThread::yieldCurrentThread(); +} + Mutex::Mutex() : m_mutex(new QMutex()) { diff --git a/JavaScriptCore/yarr/RegexJIT.cpp b/JavaScriptCore/yarr/RegexJIT.cpp index 609417f..9eff75a 100644 --- a/JavaScriptCore/yarr/RegexJIT.cpp +++ b/JavaScriptCore/yarr/RegexJIT.cpp @@ -1032,6 +1032,9 @@ class RegexGenerator : private MacroAssembler { TermGenerationState parenthesesState(disjunction, state.checkedTotal); Label matchAgain(this); + + storeToFrame(index, parenthesesTerm.frameLocation); // Save the current index to check for zero len matches later. + for (parenthesesState.resetAlternative(); parenthesesState.alternativeValid(); parenthesesState.nextAlternative()) { PatternAlternative* alternative = parenthesesState.alternative(); @@ -1046,9 +1049,9 @@ class RegexGenerator : private MacroAssembler { for (parenthesesState.resetTerm(); parenthesesState.termValid(); parenthesesState.nextTerm()) generateTerm(parenthesesState); - // If we get here, we matched! Limit not yet supported, so just try to match more! - jump(matchAgain); - + // If we get here, we matched! If the index advanced then try to match more since limit isn't supported yet. + branch32(GreaterThan, index, Address(stackPointerRegister, (parenthesesTerm.frameLocation * sizeof(void*))), matchAgain); + parenthesesState.linkAlternativeBacktracks(this); // We get here if the alternative fails to match - fall through to the next iteration, or out of the loop. |