X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/14957cd040308e3eeec43d26bae5d76da13fcd85..2d39b0e377c0896910ee49ae70082ba665faf986:/create_hash_table diff --git a/create_hash_table b/create_hash_table index 59b574a..88e8447 100755 --- a/create_hash_table +++ b/create_hash_table @@ -41,6 +41,10 @@ my @keys = (); my @attrs = (); my @values = (); my @hashes = (); +my @table = (); +my @links = (); + +my $hasSetter = "false"; my $inside = 0; my $name; @@ -74,6 +78,8 @@ while () { @attrs = (); @values = (); @hashes = (); + @table = (); + @links = (); $inside = 0; } elsif (/^(\S+)\s*(\S+)\s*([\w\|]*)\s*(\w*)\s*$/ && $inside) { @@ -90,7 +96,11 @@ while () { #printf STDERR "WARNING: Number of arguments missing for $key/$val\n" if (length($param) == 0); } elsif (length($att)) { my $get = $val; - my $put = !($att =~ m/ReadOnly/) ? "set" . jsc_ucfirst($val) : "0"; + my $put = "0"; + if (!($att =~ m/ReadOnly/)) { + $put = "set" . jsc_ucfirst($val); + } + $hasSetter = "true"; push(@values, { "type" => "Property", "get" => $get, "put" => $put }); } else { push(@values, { "type" => "Lexer", "value" => $val }); @@ -149,8 +159,6 @@ sub leftShift($$) { sub calcCompactHashSize() { - my @table = (); - my @links = (); my $compactHashSize = ceilingToPowerOf2(2 * @keys); $compactHashSizeMask = $compactHashSize - 1; $compactSize = $compactHashSize; @@ -179,7 +187,6 @@ sub calcCompactHashSize() # Paul Hsieh's SuperFastHash # http://www.azillionmonkeys.com/qed/hash.html -# Ported from UString.. sub hashValue($) { my @chars = split(/ */, $_[0]); @@ -207,7 +214,7 @@ sub hashValue($) { } # Handle end case - if ($rem !=0) { + if ($rem != 0) { $hash += ord($chars[$s]); $hash ^= (leftShift($hash, 11)% $EXP2_32); $hash += $hash >> 17; @@ -221,11 +228,15 @@ sub hashValue($) { $hash += ($hash >> 15); $hash = $hash% $EXP2_32; $hash ^= (leftShift($hash, 10)% $EXP2_32); - - # this avoids ever returning a hash code of 0, since that is used to - # signal "hash not computed yet", using a value that is likely to be - # effectively the same as 0 when the low bits are masked - $hash = 0x80000000 if ($hash == 0); + + # Save 8 bits for StringImpl to use as flags. + $hash &= 0xffffff; + + # This avoids ever returning a hash code of 0, since that is used to + # signal "hash not computed yet". Setting the high bit maintains + # reasonable fidelity to a hash code of 0 because it is likely to yield + # exactly 0 when hash lookup masks out the high bits. + $hash = (0x80000000 >> 8) if ($hash == 0); return $hash; } @@ -238,62 +249,78 @@ sub output() { my $nameEntries = "${name}Values"; $nameEntries =~ s/:/_/g; + my $nameIndex = "${name}Index"; + $nameIndex =~ s/:/_/g; + print "\n#include \"JSCBuiltins.h\"\n"; print "\n#include \"Lookup.h\"\n" if ($includelookup); + if ($useNameSpace) { print "\nnamespace ${useNameSpace} {\n"; print "\nusing namespace JSC;\n"; } else { print "\nnamespace JSC {\n"; } - my $count = scalar @keys + 1; - print "#if ENABLE(JIT)\n"; - print "#define THUNK_GENERATOR(generator) , generator\n"; - print "#else\n"; - print "#define THUNK_GENERATOR(generator)\n"; - print "#endif\n"; - print "\nstatic const struct HashTableValue ${nameEntries}\[$count\] = {\n"; + + print "\nstatic const struct CompactHashIndex ${nameIndex}\[$compactSize\] = {\n"; + for (my $i = 0; $i < $compactSize; $i++) { + my $T = -1; + if (defined($table[$i])) { $T = $table[$i]; } + my $L = -1; + if (defined($links[$i])) { $L = $links[$i]; } + print " { $T, $L },\n"; + } + print "};\n\n"; + + my $packedSize = scalar @keys; + print "\nstatic const struct HashTableValue ${nameEntries}\[$packedSize\] = {\n"; my $i = 0; foreach my $key (@keys) { my $firstValue = ""; my $secondValue = ""; - my $castStr = ""; + my $firstCastStr = ""; + my $secondCastStr = ""; if ($values[$i]{"type"} eq "Function") { - $castStr = "static_cast"; + $firstCastStr = "static_cast"; $firstValue = $values[$i]{"function"}; $secondValue = $values[$i]{"params"}; } elsif ($values[$i]{"type"} eq "Property") { - $castStr = "static_cast"; + $firstCastStr = "static_cast"; + $secondCastStr = "static_cast"; $firstValue = $values[$i]{"get"}; $secondValue = $values[$i]{"put"}; } elsif ($values[$i]{"type"} eq "Lexer") { $firstValue = $values[$i]{"value"}; $secondValue = "0"; } - my $thunkGenerator = "0"; - if ($key eq "charCodeAt") { - $thunkGenerator = "charCodeAtThunkGenerator"; - } - if ($key eq "charAt") { - $thunkGenerator = "charAtThunkGenerator"; + + my $intrinsic = "NoIntrinsic"; + $intrinsic = "FromCharCodeIntrinsic" if ($key eq "fromCharCode"); + if ($name eq "arrayPrototypeTable") { + $intrinsic = "ArrayPushIntrinsic" if ($key eq "push"); + $intrinsic = "ArrayPopIntrinsic" if ($key eq "pop"); } - if ($key eq "sqrt") { - $thunkGenerator = "sqrtThunkGenerator"; + if ($name eq "regExpPrototypeTable") { + $intrinsic = "RegExpExecIntrinsic" if ($key eq "exec"); + $intrinsic = "RegExpTestIntrinsic" if ($key eq "test"); } - if ($key eq "pow") { - $thunkGenerator = "powThunkGenerator"; + + if ($values[$i]{"type"} eq "Function") { + my $tableHead = $name; + $tableHead =~ s/Table$//; + print " #if JSC_BUILTIN_EXISTS(" . uc($tableHead . $key) .")\n"; + print " { \"$key\", (($attrs[$i]) & ~Function) | Builtin, $intrinsic, (intptr_t)static_cast(" . $tableHead . ucfirst($key) . "CodeGenerator), (intptr_t)$secondValue },\n"; + print " #else\n" } - if ($key eq "fromCharCode") { - $thunkGenerator = "fromCharCodeThunkGenerator"; + print " { \"$key\", $attrs[$i], $intrinsic, (intptr_t)" . $firstCastStr . "($firstValue), (intptr_t)" . $secondCastStr . "($secondValue) },\n"; + if ($values[$i]{"type"} eq "Function") { + print " #endif\n" } - print " { \"$key\", $attrs[$i], (intptr_t)" . $castStr . "($firstValue), (intptr_t)$secondValue THUNK_GENERATOR($thunkGenerator) },\n"; $i++; } - print " { 0, 0, 0, 0 THUNK_GENERATOR(0) }\n"; print "};\n\n"; - print "#undef THUNK_GENERATOR\n"; - print "extern JSC_CONST_HASHTABLE HashTable $name =\n"; - print " \{ $compactSize, $compactHashSizeMask, $nameEntries, 0 \};\n"; + print "extern const struct HashTable $name =\n"; + print " \{ $packedSize, $compactHashSizeMask, $hasSetter, $nameEntries, 0, $nameIndex \};\n"; print "} // namespace\n"; }