| Differences between
and this patch
- Source/JavaScriptCore/ChangeLog +35 lines
Lines 1-3 Source/JavaScriptCore/ChangeLog_sec1
1
2011-02-11  Siddharth Mathur  <siddharth.mathur@nokia.com>
2
3
        Reviewed by NOBODY (OOPS!).
4
5
        [Symbian] OSAllocator implementation for Symbian OS. 
6
        Manages both data and code region requests. V8 and Sunspider work nicely with JSC interpreter.
7
        Not tested with JSC JIT yet as it has unrelated failures. Also no thread safety yet.   
8
        https://bugs.webkit.org/show_bug.cgi?id=51128
9
10
        * JavaScriptCore.pri: removed HAL linkage
11
        * wtf/Bitmap.h:
12
        (WTF::::findRunOfZeros): find run of zeros in a bitmap. quick n dirty
13
        * wtf/OSAllocator.h:
14
        (WTF::OSAllocator::decommitAndRelease): decommit explicitly 
15
        * wtf/OSAllocatorSymbian.cpp: Impl. of OSAllocator interface 
16
        (WTF::allocateCodeChunk): utility for code chunks
17
        (WTF::deallocateCodeChunk): utility for code chunks
18
        (WTF::dataAllocatorInstance): getter for data allocator instance
19
        (WTF::OSAllocator::reserveUncommitted):
20
        (WTF::OSAllocator::releaseDecommitted):
21
        (WTF::OSAllocator::commit):
22
        (WTF::OSAllocator::decommit):
23
        (WTF::OSAllocator::reserveAndCommit):
24
        (WTF::PageAllocatorSymbian::PageAllocatorSymbian): piggybacks multiple requests on 1 Symbian chunk
25
        (WTF::PageAllocatorSymbian::~PageAllocatorSymbian):
26
        (WTF::PageAllocatorSymbian::reserve):
27
        (WTF::PageAllocatorSymbian::release):
28
        (WTF::PageAllocatorSymbian::commit):
29
        (WTF::PageAllocatorSymbian::decommit):
30
        (WTF::PageAllocatorSymbian::contains):
31
        * wtf/PageAllocatorSymbian.h: Added.
32
        (WTF::ChunkWithMetadata::ChunkWithMetadata): wrapper around RChunk  
33
        (WTF::ChunkWithMetadata::~ChunkWithMetadata):
34
        (WTF::ChunkWithMetadata::contains):
35
1
2011-02-11  Adam Barth  <abarth@webkit.org>
36
2011-02-11  Adam Barth  <abarth@webkit.org>
2
37
3
        Reviewed by Andreas Kling.
38
        Reviewed by Andreas Kling.
- Source/JavaScriptCore/JavaScriptCore.pri -6 lines
Lines 48-59 symbian { Source/JavaScriptCore/JavaScriptCore.pri_sec1
48
    INCLUDEPATH = $$JAVASCRIPTCORE_INCLUDEPATH $$INCLUDEPATH
48
    INCLUDEPATH = $$JAVASCRIPTCORE_INCLUDEPATH $$INCLUDEPATH
49
}
49
}
50
50
51
symbian: {
52
    LIBS += -lhal
53
    # For hal.h
54
    INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE
55
}
56
57
win32-*: DEFINES += _HAS_TR1=0
51
win32-*: DEFINES += _HAS_TR1=0
58
52
59
DEFINES += BUILDING_JavaScriptCore BUILDING_WTF
53
DEFINES += BUILDING_JavaScriptCore BUILDING_WTF
- Source/JavaScriptCore/wtf/Bitmap.h +21 lines
Lines 39-44 public: Source/JavaScriptCore/wtf/Bitmap.h_sec1
39
    void clear(size_t);
39
    void clear(size_t);
40
    void clearAll();
40
    void clearAll();
41
    void advanceToNextFreeBit(size_t&) const;
41
    void advanceToNextFreeBit(size_t&) const;
42
    int64_t findRunOfZeros(size_t) const;
42
    size_t count(size_t = 0) const;
43
    size_t count(size_t = 0) const;
43
    size_t isEmpty() const;
44
    size_t isEmpty() const;
44
    size_t isFull() const;
45
    size_t isFull() const;
Lines 97-102 inline void Bitmap<size>::advanceToNextF Source/JavaScriptCore/wtf/Bitmap.h_sec2
97
}
98
}
98
99
99
template<size_t size>
100
template<size_t size>
101
inline int64_t Bitmap<size>::findRunOfZeros(size_t runLength) const
102
{
103
    if (!runLength) 
104
            runLength = 1; 
105
     
106
    for (size_t i = 0; i <= (size - runLength) ; i++) {
107
        bool found = true; 
108
        for (size_t j = i; j <= (i + runLength - 1) ; j++) { 
109
            if (get(j)) {
110
                found = false; 
111
                break;
112
            }
113
        }
114
        if (found)  
115
            return i; 
116
    }
117
    return -1;
118
}
119
120
template<size_t size>
100
inline size_t Bitmap<size>::count(size_t start) const
121
inline size_t Bitmap<size>::count(size_t start) const
101
{
122
{
102
    size_t result = 0;
123
    size_t result = 0;
- Source/JavaScriptCore/wtf/OSAllocator.h -3 / +1 lines
Lines 77-85 inline void* OSAllocator::reserveAndComm Source/JavaScriptCore/wtf/OSAllocator.h_sec1
77
inline void OSAllocator::decommitAndRelease(void* releaseBase, size_t releaseSize, void* decommitBase, size_t decommitSize)
77
inline void OSAllocator::decommitAndRelease(void* releaseBase, size_t releaseSize, void* decommitBase, size_t decommitSize)
78
{
78
{
79
    ASSERT(decommitBase >= releaseBase && (static_cast<char*>(decommitBase) + decommitSize) <= (static_cast<char*>(releaseBase) + releaseSize));
79
    ASSERT(decommitBase >= releaseBase && (static_cast<char*>(decommitBase) + decommitSize) <= (static_cast<char*>(releaseBase) + releaseSize));
80
#if OS(WINCE)
80
#if OS(WINCE) || OS(SYMBIAN)
81
    // On most platforms we can actually skip this final decommit; releasing the VM will
82
    // implicitly decommit any physical memory in the region. This is not true on WINCE.
83
    decommit(decommitBase, decommitSize);
81
    decommit(decommitBase, decommitSize);
84
#else
82
#else
85
    UNUSED_PARAM(decommitBase);
83
    UNUSED_PARAM(decommitBase);
- Source/JavaScriptCore/wtf/OSAllocatorSymbian.cpp -9 / +158 lines
Lines 1-5 Source/JavaScriptCore/wtf/OSAllocatorSymbian.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2010 Apple Inc. All rights reserved.
2
 * Copyright (C) 2010 Apple Inc. All rights reserved.
3
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
3
 *
4
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
Lines 26-56 Source/JavaScriptCore/wtf/OSAllocatorSymbian.cpp_sec2
26
#include "config.h"
27
#include "config.h"
27
#include "OSAllocator.h"
28
#include "OSAllocator.h"
28
29
29
#include <wtf/FastMalloc.h>
30
#include "PageAllocatorSymbian.h"
30
31
31
namespace WTF {
32
namespace WTF {
32
33
33
void* OSAllocator::reserveUncommitted(size_t bytes, Usage, bool, bool)
34
// Array to store code chunks used by JIT engine(s)
35
static RPointerArray<ChunkWithMetadata> codeChunksContainer;
36
37
// Pointer to the data (non code) allocator
38
static PageAllocatorSymbian* allocator = 0; 
39
40
_LIT(KErrorStringInternalConsistency, "OSAllocator:ConsistencyError");
41
_LIT(KErrorStringChunkCreation, "OSAllocator:ChunkInitError");
42
_LIT(KErrorStringPageSize, "OSAllocator:WrongPageSize");
43
44
// Makes a new code chunk for a JIT engine with everything in committed state
45
static void* allocateCodeChunk(size_t bytes) 
46
{
47
    RChunk c; 
48
    TInt error = c.CreateLocalCode(bytes, bytes);
49
    __ASSERT_ALWAYS(error == KErrNone, User::Panic(KErrorStringChunkCreation, error));
50
   
51
    codeChunksContainer.Append(new ChunkWithMetadata(c.Handle())); 
52
    return static_cast<void*>(c.Base()); 
53
}
54
   
55
// Frees the _entire_ code chunk in which this address resides. 
56
static bool deallocateCodeChunk(void* address) 
57
{     
58
    bool found = false; 
59
    for (int i = 0; i < codeChunksContainer.Count(); i++) { 
60
        ChunkWithMetadata* p = codeChunksContainer[i];
61
        if (p && p->contains(address)) { 
62
            codeChunksContainer.Remove(i);
63
            delete p;
64
            found = true;
65
        }
66
    }
67
    return found; 
68
}
69
70
// Return the (singleton) object that manages all non-code VM operations
71
static PageAllocatorSymbian* dataAllocatorInstance() 
34
{
72
{
35
    return fastMalloc(bytes);
73
    if (!allocator) 
74
        allocator = new PageAllocatorSymbian();
75
76
    return allocator; 
36
}
77
}
37
78
38
void* OSAllocator::reserveAndCommit(size_t bytes, Usage, bool, bool)
79
// Reserve memory and return the base address of the region
80
void* OSAllocator::reserveUncommitted(size_t reservationSize, Usage usage, bool , bool executable) 
39
{
81
{
40
    return fastMalloc(bytes);
82
    void* base = 0; 
83
    if (executable) 
84
        base = allocateCodeChunk(reservationSize);
85
    else
86
        base = dataAllocatorInstance()->reserve(reservationSize);
87
    return base; 
41
}
88
}
42
89
43
void OSAllocator::commit(void*, size_t, bool, bool)
90
// Inverse operation of reserveUncommitted()
91
void OSAllocator::releaseDecommitted(void* parkedBase, size_t bytes) 
44
{
92
{
93
    if (dataAllocatorInstance()->contains(parkedBase)) 
94
        dataAllocatorInstance()->release(parkedBase, bytes);
95
96
    // NOOP for code chunks (JIT) because we released them in decommit()
45
}
97
}
46
98
47
void OSAllocator::decommit(void*, size_t)
99
// Commit what was previously reserved via reserveUncommitted()
100
void OSAllocator::commit(void* address, size_t bytes, bool, bool executable) 
48
{
101
{
102
    // For code chunks, we commit (early) in reserveUncommitted(), so NOOP
103
    // For data regions, do real work
104
    if (!executable) 
105
        dataAllocatorInstance()->commit(address, bytes);
106
}
107
108
void OSAllocator::decommit(void* address, size_t bytes) 
109
{ 
110
    if (dataAllocatorInstance()->contains(address))
111
        dataAllocatorInstance()->decommit(address, bytes);
112
    else
113
        deallocateCodeChunk(address); // for code chunk, decommit AND release    
114
}
115
    
116
void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable)
117
{ 
118
    void* base = reserveUncommitted(bytes, usage, writable, executable);
119
    commit(base, bytes, writable, executable);
120
    return base;
121
}
122
123
124
// The PageAllocatorSymbian class helps map OSAllocator calls for reserve/commit/decommit
125
// to a single large Symbian chunk. Only works with multiples of page size, and as a corollary 
126
// all addresses accepted or returned by it are also page-sized aligned. 
127
// Design notes: 
128
// - We initialize a chunk up-front with a large reservation size
129
// - The entire reservation reserve is logically divided into pageSized blocks (4K on Symbian) 
130
// - The map maintains 1 bit for each of the 4K-sized region in our address space
131
// - OSAllocator::reserveUncommitted() requests lead to 1 or more bits being set in map 
132
//   to indicate internally reserved state. The VM address corresponding to the first bit is returned. 
133
// - OSAllocator::commit() actually calls RChunk.commit() and commits *all or part* of the region 
134
//   reserved via reserveUncommitted() previously. 
135
// - OSAllocator::decommit() calls RChunk.decommit() 
136
// - OSAllocator::releaseDecommitted() unparks all the bits in the map, but trusts that a previously
137
//   call to decommit() would have returned the memory to the OS 
138
PageAllocatorSymbian::PageAllocatorSymbian()
139
{        
140
    __ASSERT_ALWAYS(m_pageSize == WTF::pageSize(), User::Panic(KErrorStringPageSize, m_pageSize));
141
    
142
    RChunk chunk;
143
    TInt error = chunk.CreateDisconnectedLocal(0, 0, TInt(largeReservationSize));
144
    __ASSERT_ALWAYS(error == KErrNone, User::Panic(KErrorStringChunkCreation, error));
145
    
146
    m_chunkWithMeta = new ChunkWithMetadata(chunk.Handle()); // takes ownership of chunk
147
}
148
149
PageAllocatorSymbian::~PageAllocatorSymbian() 
150
{
151
    delete m_chunkWithMeta;
152
}
153
154
// Reserves a region internally in the bitmap
155
void* PageAllocatorSymbian::reserve(size_t bytes) 
156
{ 
157
    // Find first available region
158
    const size_t nPages = bytes / m_pageSize;
159
    const int64_t startIdx = m_map.findRunOfZeros(nPages);
160
161
    // Pseudo OOM
162
    if (startIdx < 0)
163
        return 0;
164
    
165
    for (size_t i = startIdx; i < startIdx + nPages ; i++)
166
        m_map.set(i);
167
    
168
    return static_cast<void*>( m_chunkWithMeta->m_base + (TUint)(m_pageSize * startIdx) ); 
169
}
170
171
// Reverses the effects of a reserve() call
172
void PageAllocatorSymbian::release(void* address, size_t bytes)
173
{
174
    const size_t startIdx = (static_cast<char*>(address) - m_chunkWithMeta->m_base) / m_pageSize;
175
    const size_t nPages = bytes / m_pageSize;
176
    for (size_t i = startIdx; i < startIdx + nPages ; i++)
177
        m_map.clear(i);
178
}
179
180
// Actually commit memory from the OS, after a previous call to reserve()
181
bool PageAllocatorSymbian::commit(void* address, size_t bytes) 
182
{ 
183
    // sanity check that bits were previously set
184
    const size_t idx = (static_cast<char*>(address) - m_chunkWithMeta->m_base) / m_pageSize;
185
    const size_t nPages = bytes / m_pageSize;
186
    __ASSERT_ALWAYS(m_map.get(idx), User::Panic(KErrorStringInternalConsistency, idx));
187
    __ASSERT_ALWAYS(m_map.get(idx+nPages-1), User::Panic(KErrorStringInternalConsistency, idx+nPages-1));
188
    
189
    TInt error = m_chunkWithMeta->Commit(static_cast<char*>(address) - m_chunkWithMeta->m_base, bytes);
190
    return (error == KErrNone);
191
}
192
193
// Inverse operation of commit(), a release() should follow later
194
bool PageAllocatorSymbian::decommit(void* address, size_t bytes) 
195
{ 
196
    TInt error = m_chunkWithMeta->Decommit(static_cast<char*>(address) - m_chunkWithMeta->m_base, bytes);
197
    return (error == KErrNone); 
49
}
198
}
50
199
51
void OSAllocator::releaseDecommitted(void* address, size_t)
200
bool PageAllocatorSymbian::contains(const void* address) const
52
{
201
{
53
    fastFree(address);
202
    return m_chunkWithMeta->contains(address);     
54
}
203
}
55
204
56
} // namespace WTF
205
} // namespace WTF
- Source/JavaScriptCore/wtf/PageAllocatorSymbian.h +101 lines
Line 0 Source/JavaScriptCore/wtf/PageAllocatorSymbian.h_sec1
1
/*
2
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 *
8
 * 1.  Redistributions of source code must retain the above copyright
9
 *     notice, this list of conditions and the following disclaimer. 
10
 * 2.  Redistributions in binary form must reproduce the above copyright
11
 *     notice, this list of conditions and the following disclaimer in the
12
 *     documentation and/or other materials provided with the distribution. 
13
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14
 *     its contributors may be used to endorse or promote products derived
15
 *     from this software without specific prior written permission. 
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
29
#ifndef PageAllocatorSymbian_h
30
#define PageAllocatorSymbian_h
31
32
#include <e32std.h>
33
#include <wtf/BitMap.h>
34
35
namespace WTF { 
36
37
size_t pageSize();
38
39
// Convenience wrapper around an RChunk
40
class ChunkWithMetadata : public RChunk {
41
   
42
public:   
43
    ChunkWithMetadata(TInt handle) 
44
    {
45
        SetHandle(handle);
46
        // prevent kernel calls by caching these
47
        
48
        m_base = reinterpret_cast<char*>(Base()); 
49
        m_maxSize = MaxSize();
50
    }
51
    
52
    ~ChunkWithMetadata() 
53
    { 
54
        Decommit(0, m_maxSize);
55
        Close();
56
    }
57
     
58
    // checks if address is in chunk's virtual address space
59
    bool contains(const void* address) const 
60
    {
61
        return (static_cast<const char*>(address) >= m_base && static_cast<const char*>(address) < (m_base + m_maxSize));  
62
    }
63
    
64
    char* m_base; 
65
    size_t m_maxSize; 
66
    
67
};
68
69
// Size of the large up-front reservation
70
#if defined(__WINS__) 
71
// Emulator has limited virtual address space
72
const size_t largeReservationSize = 96*1024*1024;
73
#else
74
// HW has plenty of virtual addresses
75
const size_t largeReservationSize = 256*1024*1024;
76
#endif
77
78
class PageAllocatorSymbian { 
79
80
public:     
81
    PageAllocatorSymbian();
82
    ~PageAllocatorSymbian();
83
    
84
    void* reserve(size_t);
85
    void release(void*, size_t);
86
    bool commit(void*, size_t);
87
    bool decommit(void*, size_t);
88
    
89
    bool contains(const void*) const; 
90
    
91
private:     
92
    static const size_t m_pageSize = 4096; 
93
    ChunkWithMetadata* m_chunkWithMeta; 
94
    Bitmap<largeReservationSize / m_pageSize> m_map;
95
    
96
};
97
98
} // namespace WTF
99
100
#endif // PageAllocatorSymbian_h
101

Return to Bug 51128