summaryrefslogtreecommitdiff
path: root/rts/RtsStartup.c
Commit message (Collapse)AuthorAgeFilesLines
* Finish stable splitDavid Feuer2018-08-291-3/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Long ago, the stable name table and stable pointer tables were one. Now, they are separate, and have significantly different implementations. I believe the time has come to finish the split that began in #7674. * Divide `rts/Stable` into `rts/StableName` and `rts/StablePtr`. * Give each table its own mutex. * Add FFI functions `hs_lock_stable_ptr_table` and `hs_unlock_stable_ptr_table` and document them. These are intended to replace the previously undocumented `hs_lock_stable_tables` and `hs_lock_stable_tables`, which are now documented as deprecated synonyms. * Make `eqStableName#` use pointer equality instead of unnecessarily comparing stable name table indices. Reviewers: simonmar, bgamari, erikd Reviewed By: bgamari Subscribers: rwbarton, carter GHC Trac Issues: #15555 Differential Revision: https://phabricator.haskell.org/D5084
* rts: Flush eventlog in hs_init_ghc (fixes #15440)Mitsutoshi Aoe2018-07-271-0/+1
| | | | | | | | | | | | | | | Without this change RTS typically doesn't flush some important events until the process terminates or it doesn't write them at all in case it terminates abnormally. Here is a list of such events: * EVENT_WALL_CLOCK_TIME * EVENT_OS_PROCESS_PID * EVENT_OS_PROCESS_PPID * EVENT_RTS_IDENTIFIER * EVENT_PROGRAM_ARGS * EVENT_PROGRAM_ENV
* Fix #15038Ömer Sinan Ağacan2018-05-101-0/+7
| | | | | | | | | | | | | | | | | | | | | We introduce a new Id for unused pointer values in unboxed sums that is not CAFFY. Because the Id is not CAFFY it doesn't make non-CAFFY definitions CAFFY, fixing #15038. To make sure anything referenced by the new id will be retained we get a stable pointer to in on RTS startup. Test Plan: Passes validate Reviewers: simonmar, simonpj, hvr, bgamari, erikd Reviewed By: simonmar Subscribers: rwbarton, thomie, carter GHC Trac Issues: #15038 Differential Revision: https://phabricator.haskell.org/D4680
* Initialize hs_init with UTF8 encoded arguments on Windows.Andreas Klebinger2017-07-271-0/+26
| | | | | | | | | | | | | | | | | | | | | | | Summary: Get utf8 encoded arguments before we call hs_init and use them instead of ignoring hs_init arguments. This reduces differing behaviour of the RTS between windows and linux and simplifies the code involved. A few testcases were changed to expect the same result on windows as on linux after the changes. This fixes #13940. Test Plan: ./validate Reviewers: austin, hvr, bgamari, erikd, simonmar, Phyx Subscribers: Phyx, rwbarton, thomie GHC Trac Issues: #13940 Differential Revision: https://phabricator.haskell.org/D3739
* Prefer #if defined to #ifdefBen Gamari2017-04-281-9/+9
| | | | Our new CPP linter enforces this.
* hs_add_root() RTS API removalSergei Trofimovich2017-04-171-11/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | Before ghc-7.2 hs_add_root() had to be used to initialize haskell modules when haskell was called from FFI. commit a52ff7619e8b7d74a9d933d922eeea49f580bca8 ("Change the way module initialisation is done (#3252, #4417)") removed needs for hs_add_root() and made function a no-op. For backward compatibility '__stginit_<module>' symbol was not removed. This change removes no-op hs_add_root() function and unused '__stginit_<module>' symbol from each haskell module. Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org> Test Plan: ./validate Reviewers: simonmar, austin, bgamari, erikd Reviewed By: simonmar Subscribers: rwbarton, thomie Differential Revision: https://phabricator.haskell.org/D3460
* Fatal if we try to reinitialize the RTSSimon Marlow2017-01-261-0/+6
| | | | | | | | | | | | | | | This isn't supported, and fatalling with an error is better than segfaulting later. Test Plan: validate Reviewers: JonCoens, austin, erikd, niteria, bgamari Reviewed By: niteria, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D3020
* Throw an exception on heap overflowDemi Obenour2017-01-101-0/+7
| | | | | | | | | | | | | | | | | This changes heap overflow to throw a HeapOverflow exception instead of killing the process. Test Plan: GHC CI Reviewers: simonmar, austin, hvr, erikd, bgamari Reviewed By: simonmar, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2790 GHC Trac Issues: #1791
* Reset FPU precision back to MSVCRT defaultsTamar Christina2016-12-151-4/+30
| | | | | | | | | | | | | | | | | | | | | | Mingw-w64 does a stupid thing. They set the FPU precision to extended mode by default. The reasoning is that it's for compatibility with GNU Linux ported libraries. However the problem is this is incompatible with the standard Windows double precision mode. In fact, if we create a new OS thread then Windows will reset the FPU to double precision mode. So we end up with a weird state where the main thread by default has a different precision than any child threads. Test Plan: ./validate new test T7289 Reviewers: simonmar, austin, bgamari, erikd Reviewed By: simonmar Subscribers: thomie, #ghc_windows_task_force Differential Revision: https://phabricator.haskell.org/D2819 GHC Trac Issues: #7289
* Overhaul of Compact Regions (#12455)Simon Marlow2016-12-071-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This commit makes various improvements and addresses some issues with Compact Regions (aka Compact Normal Forms). This was the most important thing I wanted to fix. Compaction previously prevented GC from running until it was complete, which would be a problem in a multicore setting. Now, we compact using a hand-written Cmm routine that can be interrupted at any point. When a GC is triggered during a sharing-enabled compaction, the GC has to traverse and update the hash table, so this hash table is now stored in the StgCompactNFData object. Previously, compaction consisted of a deepseq using the NFData class, followed by a traversal in C code to copy the data. This is now done in a single pass with hand-written Cmm (see rts/Compact.cmm). We no longer use the NFData instances, instead the Cmm routine evaluates components directly as it compacts. The new compaction is about 50% faster than the old one with no sharing, and a little faster on average with sharing (the cost of the hash table dominates when we're doing sharing). Static objects that don't (transitively) refer to any CAFs don't need to be copied into the compact region. In particular this means we often avoid copying Char values and small Int values, because these are static closures in the runtime. Each Compact# object can support a single compactAdd# operation at any given time, so the Data.Compact library now enforces mutual exclusion using an MVar stored in the Compact object. We now get exceptions rather than killing everything with a barf() when we encounter an object that cannot be compacted (a function, or a mutable object). We now also detect pinned objects, which can't be compacted either. The Data.Compact API has been refactored and cleaned up. A new compactSize operation returns the size (in bytes) of the compact object. Most of the documentation is in the Haddock docs for the compact library, which I've expanded and improved here. Various comments in the code have been improved, especially the main Note [Compact Normal Forms] in rts/sm/CNF.c. I've added a few tests, and expanded a few of the tests that were there. We now also run the tests with GHCi, and in a new test way that enables sanity checking (+RTS -DS). There's a benchmark in libraries/compact/tests/compact_bench.hs for measuring compaction speed and comparing sharing vs. no sharing. The field totalDataW in StgCompactNFData was unnecessary. Test Plan: * new unit tests * validate * tested manually that we can compact Data.Aeson data Reviewers: gcampax, bgamari, ezyang, austin, niteria, hvr, erikd Subscribers: thomie, simonpj Differential Revision: https://phabricator.haskell.org/D2751 GHC Trac Issues: #12455
* Use C99's boolBen Gamari2016-11-291-6/+6
| | | | | | | | | | | | Test Plan: Validate on lots of platforms Reviewers: erikd, simonmar, austin Reviewed By: erikd, simonmar Subscribers: michalt, thomie Differential Revision: https://phabricator.haskell.org/D2699
* remove unnecessary ifdefSimon Marlow2016-10-181-2/+0
|
* Support more than 64 logical processors on WindowsTamar Christina2016-10-011-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Windows support for more than 64 logical processors are implemented using processor groups. Essentially what it's doing is keeping the existing maximum of 64 processors and keeping the affinity mask a 64 bit value, but adds an hierarchy above that. This support was added to Windows 7 and so we need to at runtime detect if the APIs are still there due to our minimum supported version being Windows Vista. The Maximum number of groups supported at this time is 4, so 256 logical cores. The group indices are 0 based. One thread can have affinity with multiple groups. See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684251.aspx and particularly helpful is the whitepaper: 'Supporting Systems that have more than 64 processors' at https://msdn.microsoft.com/en-us/library/windows/hardware/dn653313.aspx Processor groups are not guaranteed to be uniformly distributed nor guaranteed to be filled before a next group is needed. The OS will assign processors to groups based on physical proximity and will never partially assign cores from one physical cpu to more than one group. If one has two 48 core CPUs then you'd end up with two groups of 48 logical cpus. Now add a 3rd CPU with 10 cores and the group it is assigned to depends where the socket is on the board. Test Plan: ./validate or make test -c . in the rts test folder. This tests for regressions, to test this particular functionality itself: <program> +RTS -N -qa -RTS Test is detailed in description. Reviewers: bgamari, simonmar, austin, erikd Reviewed By: simonmar Subscribers: thomie, #ghc_windows_task_force Differential Revision: https://phabricator.haskell.org/D2533 GHC Trac Issues: #11054
* Expose hs_exit_(rtsFalse) as hs_exit_nowait()Simon Marlow2016-09-231-0/+8
| | | | | | | | | | | | Summary: And document it. See the docmentation for the reason I want this. Test Plan: It's an existing API, just exposing it. Reviewers: bgamari, niteria, austin, erikd Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2531
* shutdownHaskellAndExit: just do a normal hs_exit() (#5402)Simon Marlow2016-09-231-4/+0
| | | | | | | | | If we want to keep the RTS alive a bit longer by having another hs_init()/hs_exit() pair in a library that will destruct itself after main() has exited, then the forced shutdown here thwarts that. I think we just "fixed" #5402 in the wrong way before, this should be better.
* Compact RegionsGiovanni Campagna2016-07-201-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | This brings in initial support for compact regions, as described in the ICFP 2015 paper "Efficient Communication and Collection with Compact Normal Forms" (Edward Z. Yang et.al.) and implemented by Giovanni Campagna. Some things may change before the 8.2 release, but I (Simon M.) wanted to get the main patch committed so that we can iterate. What documentation there is is in the Data.Compact module in the new compact package. We'll need to extend and polish the documentation before the release. Test Plan: validate (new test cases included) Reviewers: ezyang, simonmar, hvr, bgamari, austin Subscribers: vikraman, Yuras, RyanGlScott, qnikst, mboes, facundominguez, rrnewton, thomie, erikd Differential Revision: https://phabricator.haskell.org/D1264 GHC Trac Issues: #11493
* rts: Replace `nat` with `uint32_t`Erik de Castro Lopo2016-05-051-1/+1
| | | | | | | | | | | | The `nat` type was an alias for `unsigned int` with a comment saying it was at least 32 bits. We keep the typedef in case client code is using it but mark it as deprecated. Test Plan: Validated on Linux, OS X and Windows Reviewers: simonmar, austin, thomie, hvr, bgamari, hsyl20 Differential Revision: https://phabricator.haskell.org/D2166
* rts/itimer/pthread: Stop timer when ticker is stoppedBen Gamari2016-05-011-1/+6
| | | | | | | | | | | | | | | | | This reworks the pthread-based itimer implementation to disarm the timer when events aren't needed. Thanks to hsyl20 for the nice design. Test Plan: Validate Reviewers: hsyl20, simonmar, austin Reviewed By: simonmar Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2131 GHC Trac Issues: #1623, #11965
* Close ticky profiling file stream after printing (#9405)Flaviu Andrei Csernik2016-03-241-0/+3
| | | | | | | | | | | | | | Test Plan: T9405 Reviewers: simonmar, austin, bgamari Reviewed By: simonmar, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2008 GHC Trac Issues: #9405
* rts: Add LibdwPool, a pool for libdw sessionsBen Gamari2015-11-231-0/+4
| | | | Differential Revision: https://phabricator.haskell.org/D1198#40948
* rts: Kill PAPI supportBen Gamari2015-11-181-13/+0
| | | | | | | | | | | | | | | This hasn't been used for a very long time and will soon be superceded by perf_events support. Test Plan: validate Reviewers: austin, simonmar Reviewed By: austin, simonmar Subscribers: thomie, erikd Differential Revision: https://phabricator.haskell.org/D1493
* Make GHCi & TH work when the compiler is built with -profSimon Marlow2015-11-071-5/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Amazingly, there were zero changes to the byte code generator and very few changes to the interpreter - mainly because we've used good abstractions that hide the differences between profiling and non-profiling. So that bit was pleasantly straightforward, but there were a pile of other wibbles to get the whole test suite through. Note that a compiler built with -prof is now like one built with -dynamic, in that to use TH you have to build the code the same way. For dynamic, we automatically enable -dynamic-too when TH is required, but we don't have anything equivalent for profiling, so you have to explicitly use -prof when building code that uses TH with a profiled compiler. For this reason Cabal won't work with TH. We don't expect to ship a profiled compiler, so I think that's OK. Test Plan: validate with GhcProfiled=YES in validate.mk Reviewers: goldfire, bgamari, rwbarton, austin, hvr, erikd, ezyang Reviewed By: ezyang Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1407 GHC Trac Issues: #4837, #545
* tracing: Kill EVENT_STARTUPBen Gamari2015-09-051-3/+0
| | | | | This has been unnecessary for quite some time due to the create/delete capability events.
* Fix for CAF retention when dynamically loading & unloading codeSimon Marlow2015-06-081-1/+5
| | | | | | | | | | | | | In a situaion where we have some statically-linked code and we want to load and unload a series of objects, we need the CAFs in the statically-linked code to be retained indefinitely, while the CAFs in the dynamically-linked code should be GC'd as normal, so that we can detect when the code is unloadable. This was wrong before - we GC'd CAFs in the static code, leading to a crash in the rare case where we use a CAF, GC it, and then load a new object that uses it again. I also did some tidy up: RtsConfig now has a field keep_cafs to indicate whether we want CAFs to be retained in static code.
* Replace hooks by callbacks in RtsConfig (#8785)Simon Marlow2015-04-071-12/+4
| | | | | | | | | | | | Summary: Hooks rely on static linking semantics, and are broken by -Bsymbolic which we need when using dynamic linking. Test Plan: Built it Reviewers: austin, hvr, tibbe Differential Revision: https://phabricator.haskell.org/D8
* compiler: fix trac issue #9817Marios Titas2014-12-101-1/+1
| | | | | | | | | | | | | | | | | | | Summary: When we call runHandlers, we must pass it a ForeignPtr. To ensure that this happens, we introduce a wrapper that receives a plain Ptr and converts it into a ForeignPtr. Then we adjust startSignalHandlers in rts/posix/Signals.c to call the wrapper instead of calling runHandlers directly. Reviewers: hvr, austin, rwbarton, simonmar Reviewed By: austin, simonmar Subscribers: simonmar, thomie, carter Differential Revision: https://phabricator.haskell.org/D515 GHC Trac Issues: #9817
* Implement -XStaticValuesFacundo Domínguez2014-12-091-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: As proposed in [1], this extension introduces a new syntactic form `static e`, where `e :: a` can be any closed expression. The static form produces a value of type `StaticPtr a`, which works as a reference that programs can "dereference" to get the value of `e` back. References are like `Ptr`s, except that they are stable across invocations of a program. The relevant wiki pages are [2, 3], which describe the motivation/ideas and implementation plan respectively. [1] Jeff Epstein, Andrew P. Black, and Simon Peyton-Jones. Towards Haskell in the cloud. SIGPLAN Not., 46(12):118–129, September 2011. ISSN 0362-1340. [2] https://ghc.haskell.org/trac/ghc/wiki/StaticPointers [3] https://ghc.haskell.org/trac/ghc/wiki/StaticPointers/ImplementationPlan Authored-by: Facundo Domínguez <facundo.dominguez@tweag.io> Authored-by: Mathieu Boespflug <m@tweag.io> Authored-by: Alexander Vershilov <alexander.vershilov@tweag.io> Test Plan: `./validate` Reviewers: hvr, simonmar, simonpj, austin Reviewed By: simonpj, austin Subscribers: qnikst, bgamari, mboes, carter, thomie, goldfire Differential Revision: https://phabricator.haskell.org/D550 GHC Trac Issues: #7015
* Per-thread allocation counters and limitsSimon Marlow2014-11-121-0/+1
| | | | | | | | This reverts commit f0fcc41d755876a1b02d1c7c79f57515059f6417. New changes: now works on 32-bit platforms too. I added some basic support for 64-bit subtraction and comparison operations to the x86 NCG.
* rts: don't crash on 'hs_init(NULL, NULL)' in debug rtsSergei Trofimovich2014-10-101-3/+3
| | | | | | | | | | | | | | | | | Caught by T6006 as a NULL dereference: Command: ./T6006 Invalid read of size 8 at 0x660ED9: hs_init_ghc (RtsStartup.c:168) by 0x660D90: hs_init (RtsStartup.c:112) by 0x40504D: main (in /home/slyfox/dev/git/ghc-validate/testsuite/tests/rts/T6006) Address 0x0 is not stack'd, malloc'd or (recently) free'd The regression was introduced by commit cb0a503a44bf016de3d9042906c6ac0c0821ffea Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
* rts: unrust 'libbfd' debug symbols parserSergei Trofimovich2014-10-051-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Patch does the following: - fixes detection of working libbfd on modern linux platforms (where bfd_uncompress_section_contents is a macro) - disables 'bfd' by default and adds '--enable-bfd-debug' configure option. As bfd's ABI is unstable the feature is primarily useful by ghc hackers. Not done (subject for another patch): - one-time bfd object memory leak in DEBUG_LoadSymbols - in '-dynamic' mode debugging symbols are loaded only for current executable, not all libraries it is linked against. Fixes Issue #8790 Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org> Test Plan: built unregisterised ghc on amd64 and ran './hello +RTS -Di' there Reviewers: simonmar, austin Reviewed By: simonmar, austin Subscribers: thomie, simonmar, ezyang, carter Differential Revision: https://phabricator.haskell.org/D193 GHC Trac Issues: #8790
* Use LinkerInternals.h for exitLinker.Edward Z. Yang2014-10-011-1/+1
| | | | | | | | | | | | | | | | Part of remove HEAP_ALLOCED patch set (#8199) Summary: Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu> Test Plan: validate Reviewers: simonmar, austin Subscribers: simonmar, ezyang, carter, thomie Differential Revision: https://phabricator.haskell.org/D262 GHC Trac Issues: #8199
* Revert "rts: add Emacs 'Local Variables' to every .c file"Simon Marlow2014-09-291-8/+0
| | | | This reverts commit 39b5c1cbd8950755de400933cecca7b8deb4ffcd.
* rts: detabify/dewhitespace RtsStartup.cAustin Seipp2014-08-201-8/+8
| | | | Signed-off-by: Austin Seipp <austin@well-typed.com>
* rts: add Emacs 'Local Variables' to every .c fileAustin Seipp2014-07-281-0/+8
| | | | | | | | This will hopefully help ensure some basic consistency in the forward by overriding buffer variables. In particular, it sets the wrap length, the offset to 4, and turns off tabs. Signed-off-by: Austin Seipp <austin@well-typed.com>
* Fix Windows build (wibble to fix for Trac #4934)Simon Peyton Jones2014-06-111-1/+1
|
* Raise exceptions when blocked in bad FDs (fixes Trac #4934)Sergei Trofimovich2014-06-081-0/+1
| | | | | | | | | | | | | | | Before the patch any call to 'select()' with 'bad_fd' led to: - unblocking of all threads - hiding exception for 'threadWaitRead bad_fd' The patch fixes both cases in this way: after 'select()' failure we iterate over each blocked descriptor and poll individually to see it's actual status, which is: - READY (move to run queue) - BLOCKED (leave in blocked queue) - INVALID (send an IOErrror exception) Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
* Per-capability nursery weak pointer lists, fixes #9075Edward Z. Yang2014-05-291-1/+4
| | | | Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
* Only uninstall signal handlers if they were actually installed (#9068)Simon Marlow2014-05-161-2/+6
| | | | Submitted by: tomgr
* Revert "Per-thread allocation counters and limits"Simon Marlow2014-05-041-1/+0
| | | | | | | | Problems were found on 32-bit platforms, I'll commit again when I have a fix. This reverts the following commits: 54b31f744848da872c7c6366dea840748e01b5cf b0534f78a73f972e279eed4447a5687bd6a8308e
* Per-thread allocation counters and limitsSimon Marlow2014-05-021-0/+1
| | | | | | | | | | | | | | | | | | | | | | | This tracks the amount of memory allocation by each thread in a counter stored in the TSO. Optionally, when the counter drops below zero (it counts down), the thread can be sent an asynchronous exception: AllocationLimitExceeded. When this happens, given a small additional limit so that it can handle the exception. See documentation in GHC.Conc for more details. Allocation limits are similar to timeouts, but - timeouts use real time, not CPU time. Allocation limits do not count anything while the thread is blocked or in foreign code. - timeouts don't re-trigger if the thread catches the exception, allocation limits do. - timeouts can catch non-allocating loops, if you use -fno-omit-yields. This doesn't work for allocation limits. I couldn't measure any impact on benchmarks with these changes, even for nofib/smp.
* Improve the shutdownHaskellAndSignal and add fast exitDuncan Coutts2013-11-141-9/+55
| | | | | | | | | | | | | | | | | | | | | This is the RTS part of a patch to base's topHandler to handle exiting by a signal. The intended behaviour is that on Unix, throwing ExitFailure (-sig) results in the process terminating with that signal. Previously shutdownHaskellAndSignal was only used for exiting with SIGINT due to the UserInterrupt exception. Improve shutdownHaskellAndSignal to do the signal part more carefully. In particular, it (should) now reliably terminates the process one way or another. Previusly if the signal was blocked, ignored or handled then shutdownHaskellAndSignal would actually return! Also, the topHandler code has two paths a careful shutdown and a "fast exit" where it does not give finalisers a chance to run. We want to support that mode also when we want to exit by signal. So rather than the base code directly calling stg_exit as it did before, we have a fastExit bool paramater for both shutdownHaskellAnd{Exit,Signal}.
* Distinguish between hs-main cases when giving rtsopts advice.Edward Z. Yang2013-09-151-3/+12
| | | | Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
* Maintain per-generation lists of weak pointers (#7847)Takano Akio2013-06-151-1/+5
|
* Kill dead code.Austin Seipp2013-05-121-27/+11
| | | | Signed-off-by: Austin Seipp <aseipp@pobox.com>
* Build fix for dyn way on Windows; patch from nusIan Lynagh2013-02-161-0/+1
|
* Separate StablePtr and StableName tables (#7674)Simon Marlow2013-02-141-2/+2
| | | | To improve performance of StablePtr.
* Enable FileLock for win32 (#4363)Paolo Capriotti2012-05-081-5/+1
|
* Move getMonotonicUSec from base to the RTS.Paolo Capriotti2012-05-081-0/+3
|
* hs_init(): cope with argc and/or argv being NULL (#6006)Simon Marlow2012-04-271-1/+8
|
* (some) tabs -> spacesGabor Greif2012-02-271-1/+1
|