Commit 0fb57e51 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Check that external references are registered in the serializer.

Inspired by a patch by Slava Chigrin <vchigrin@yandex-team.ru>

R=jkummerow@chromium.org, vchigrin@yandex-team.ru

Review URL: https://codereview.chromium.org/441983002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22896 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent cbb12d66
...@@ -42,6 +42,7 @@ def _V8PresubmitChecks(input_api, output_api): ...@@ -42,6 +42,7 @@ def _V8PresubmitChecks(input_api, output_api):
from presubmit import CppLintProcessor from presubmit import CppLintProcessor
from presubmit import SourceProcessor from presubmit import SourceProcessor
from presubmit import CheckGeneratedRuntimeTests from presubmit import CheckGeneratedRuntimeTests
from presubmit import CheckExternalReferenceRegistration
results = [] results = []
if not CppLintProcessor().Run(input_api.PresubmitLocalPath()): if not CppLintProcessor().Run(input_api.PresubmitLocalPath()):
...@@ -53,6 +54,9 @@ def _V8PresubmitChecks(input_api, output_api): ...@@ -53,6 +54,9 @@ def _V8PresubmitChecks(input_api, output_api):
if not CheckGeneratedRuntimeTests(input_api.PresubmitLocalPath()): if not CheckGeneratedRuntimeTests(input_api.PresubmitLocalPath()):
results.append(output_api.PresubmitError( results.append(output_api.PresubmitError(
"Generated runtime tests check failed")) "Generated runtime tests check failed"))
if not CheckExternalReferenceRegistration(input_api.PresubmitLocalPath()):
results.append(output_api.PresubmitError(
"External references registration check failed"))
return results return results
......
...@@ -797,6 +797,7 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm, ...@@ -797,6 +797,7 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
DCHECK(!temp1.is(temp3)); DCHECK(!temp1.is(temp3));
DCHECK(!temp2.is(temp3)); DCHECK(!temp2.is(temp3));
DCHECK(ExternalReference::math_exp_constants(0).address() != NULL); DCHECK(ExternalReference::math_exp_constants(0).address() != NULL);
DCHECK(!masm->serializer_enabled()); // External references not serializable.
Label zero, infinity, done; Label zero, infinity, done;
......
...@@ -520,6 +520,7 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm, ...@@ -520,6 +520,7 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
double_temp1, double_temp2, double_temp1, double_temp2,
temp1, temp2, temp3)); temp1, temp2, temp3));
DCHECK(ExternalReference::math_exp_constants(0).address() != NULL); DCHECK(ExternalReference::math_exp_constants(0).address() != NULL);
DCHECK(!masm->serializer_enabled()); // External references not serializable.
Label done; Label done;
DoubleRegister double_temp3 = result; DoubleRegister double_temp3 = result;
......
...@@ -105,9 +105,6 @@ struct DoubleConstant BASE_EMBEDDED { ...@@ -105,9 +105,6 @@ struct DoubleConstant BASE_EMBEDDED {
double min_int; double min_int;
double one_half; double one_half;
double minus_one_half; double minus_one_half;
double minus_zero;
double zero;
double uint8_max_value;
double negative_infinity; double negative_infinity;
double canonical_non_hole_nan; double canonical_non_hole_nan;
double the_hole_nan; double the_hole_nan;
...@@ -905,9 +902,6 @@ void ExternalReference::SetUp() { ...@@ -905,9 +902,6 @@ void ExternalReference::SetUp() {
double_constants.min_int = kMinInt; double_constants.min_int = kMinInt;
double_constants.one_half = 0.5; double_constants.one_half = 0.5;
double_constants.minus_one_half = -0.5; double_constants.minus_one_half = -0.5;
double_constants.minus_zero = -0.0;
double_constants.uint8_max_value = 255;
double_constants.zero = 0.0;
double_constants.canonical_non_hole_nan = base::OS::nan_value(); double_constants.canonical_non_hole_nan = base::OS::nan_value();
double_constants.the_hole_nan = BitCast<double>(kHoleNanInt64); double_constants.the_hole_nan = BitCast<double>(kHoleNanInt64);
double_constants.negative_infinity = -V8_INFINITY; double_constants.negative_infinity = -V8_INFINITY;
...@@ -1165,13 +1159,6 @@ ExternalReference ExternalReference::new_space_allocation_top_address( ...@@ -1165,13 +1159,6 @@ ExternalReference ExternalReference::new_space_allocation_top_address(
} }
ExternalReference ExternalReference::heap_always_allocate_scope_depth(
Isolate* isolate) {
Heap* heap = isolate->heap();
return ExternalReference(heap->always_allocate_scope_depth_address());
}
ExternalReference ExternalReference::new_space_allocation_limit_address( ExternalReference ExternalReference::new_space_allocation_limit_address(
Isolate* isolate) { Isolate* isolate) {
return ExternalReference(isolate->heap()->NewSpaceAllocationLimitAddress()); return ExternalReference(isolate->heap()->NewSpaceAllocationLimitAddress());
...@@ -1264,23 +1251,6 @@ ExternalReference ExternalReference::address_of_minus_one_half() { ...@@ -1264,23 +1251,6 @@ ExternalReference ExternalReference::address_of_minus_one_half() {
} }
ExternalReference ExternalReference::address_of_minus_zero() {
return ExternalReference(
reinterpret_cast<void*>(&double_constants.minus_zero));
}
ExternalReference ExternalReference::address_of_zero() {
return ExternalReference(reinterpret_cast<void*>(&double_constants.zero));
}
ExternalReference ExternalReference::address_of_uint8_max_value() {
return ExternalReference(
reinterpret_cast<void*>(&double_constants.uint8_max_value));
}
ExternalReference ExternalReference::address_of_negative_infinity() { ExternalReference ExternalReference::address_of_negative_infinity() {
return ExternalReference( return ExternalReference(
reinterpret_cast<void*>(&double_constants.negative_infinity)); reinterpret_cast<void*>(&double_constants.negative_infinity));
......
...@@ -866,8 +866,6 @@ class ExternalReference BASE_EMBEDDED { ...@@ -866,8 +866,6 @@ class ExternalReference BASE_EMBEDDED {
// Static variable Heap::NewSpaceStart() // Static variable Heap::NewSpaceStart()
static ExternalReference new_space_start(Isolate* isolate); static ExternalReference new_space_start(Isolate* isolate);
static ExternalReference new_space_mask(Isolate* isolate); static ExternalReference new_space_mask(Isolate* isolate);
static ExternalReference heap_always_allocate_scope_depth(Isolate* isolate);
static ExternalReference new_space_mark_bits(Isolate* isolate);
// Write barrier. // Write barrier.
static ExternalReference store_buffer_top(Isolate* isolate); static ExternalReference store_buffer_top(Isolate* isolate);
...@@ -901,9 +899,6 @@ class ExternalReference BASE_EMBEDDED { ...@@ -901,9 +899,6 @@ class ExternalReference BASE_EMBEDDED {
static ExternalReference address_of_min_int(); static ExternalReference address_of_min_int();
static ExternalReference address_of_one_half(); static ExternalReference address_of_one_half();
static ExternalReference address_of_minus_one_half(); static ExternalReference address_of_minus_one_half();
static ExternalReference address_of_minus_zero();
static ExternalReference address_of_zero();
static ExternalReference address_of_uint8_max_value();
static ExternalReference address_of_negative_infinity(); static ExternalReference address_of_negative_infinity();
static ExternalReference address_of_canonical_non_hole_nan(); static ExternalReference address_of_canonical_non_hole_nan();
static ExternalReference address_of_the_hole_nan(); static ExternalReference address_of_the_hole_nan();
......
...@@ -929,6 +929,7 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm, ...@@ -929,6 +929,7 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
DCHECK(!result.is(double_scratch)); DCHECK(!result.is(double_scratch));
DCHECK(!temp1.is(temp2)); DCHECK(!temp1.is(temp2));
DCHECK(ExternalReference::math_exp_constants(0).address() != NULL); DCHECK(ExternalReference::math_exp_constants(0).address() != NULL);
DCHECK(!masm->serializer_enabled()); // External references not serializable.
Label done; Label done;
......
...@@ -3128,6 +3128,7 @@ void MacroAssembler::CheckPageFlagForMap( ...@@ -3128,6 +3128,7 @@ void MacroAssembler::CheckPageFlagForMap(
Label::Distance condition_met_distance) { Label::Distance condition_met_distance) {
DCHECK(cc == zero || cc == not_zero); DCHECK(cc == zero || cc == not_zero);
Page* page = Page::FromAddress(map->address()); Page* page = Page::FromAddress(map->address());
DCHECK(!serializer_enabled()); // Serializer cannot match page_flags.
ExternalReference reference(ExternalReference::page_flags(page)); ExternalReference reference(ExternalReference::page_flags(page));
// The inlined static address check of the page's flags relies // The inlined static address check of the page's flags relies
// on maps never being compacted. // on maps never being compacted.
......
...@@ -1099,6 +1099,7 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm, ...@@ -1099,6 +1099,7 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
DCHECK(!temp1.is(temp3)); DCHECK(!temp1.is(temp3));
DCHECK(!temp2.is(temp3)); DCHECK(!temp2.is(temp3));
DCHECK(ExternalReference::math_exp_constants(0).address() != NULL); DCHECK(ExternalReference::math_exp_constants(0).address() != NULL);
DCHECK(!masm->serializer_enabled()); // External references not serializable.
Label zero, infinity, done; Label zero, infinity, done;
......
This diff is collapsed.
...@@ -17,17 +17,16 @@ namespace internal { ...@@ -17,17 +17,16 @@ namespace internal {
// A TypeCode is used to distinguish different kinds of external reference. // A TypeCode is used to distinguish different kinds of external reference.
// It is a single bit to make testing for types easy. // It is a single bit to make testing for types easy.
enum TypeCode { enum TypeCode {
UNCLASSIFIED, // One-of-a-kind references. UNCLASSIFIED, // One-of-a-kind references.
C_BUILTIN,
BUILTIN, BUILTIN,
RUNTIME_FUNCTION, RUNTIME_FUNCTION,
IC_UTILITY, IC_UTILITY,
STATS_COUNTER, STATS_COUNTER,
TOP_ADDRESS, TOP_ADDRESS,
C_BUILTIN,
EXTENSION,
ACCESSOR, ACCESSOR,
RUNTIME_ENTRY,
STUB_CACHE_TABLE, STUB_CACHE_TABLE,
RUNTIME_ENTRY,
LAZY_DEOPTIMIZATION LAZY_DEOPTIMIZATION
}; };
...@@ -81,8 +80,12 @@ class ExternalReferenceTable { ...@@ -81,8 +80,12 @@ class ExternalReferenceTable {
// For other types of references, the caller will figure out the address. // For other types of references, the caller will figure out the address.
void Add(Address address, TypeCode type, uint16_t id, const char* name); void Add(Address address, TypeCode type, uint16_t id, const char* name);
void Add(Address address, const char* name) {
Add(address, UNCLASSIFIED, ++max_id_[UNCLASSIFIED], name);
}
List<ExternalReferenceEntry> refs_; List<ExternalReferenceEntry> refs_;
int max_id_[kTypeCodeCount]; uint16_t max_id_[kTypeCodeCount];
}; };
......
...@@ -585,6 +585,7 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm, ...@@ -585,6 +585,7 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
DCHECK(!result.is(double_scratch)); DCHECK(!result.is(double_scratch));
DCHECK(!temp1.is(temp2)); DCHECK(!temp1.is(temp2));
DCHECK(ExternalReference::math_exp_constants(0).address() != NULL); DCHECK(ExternalReference::math_exp_constants(0).address() != NULL);
DCHECK(!masm->serializer_enabled()); // External references not serializable.
Label done; Label done;
......
...@@ -116,21 +116,21 @@ TEST(ExternalReferenceEncoder) { ...@@ -116,21 +116,21 @@ TEST(ExternalReferenceEncoder) {
encoder.Encode(total_compile_size.address())); encoder.Encode(total_compile_size.address()));
ExternalReference stack_limit_address = ExternalReference stack_limit_address =
ExternalReference::address_of_stack_limit(isolate); ExternalReference::address_of_stack_limit(isolate);
CHECK_EQ(make_code(UNCLASSIFIED, 4), CHECK_EQ(make_code(UNCLASSIFIED, 2),
encoder.Encode(stack_limit_address.address())); encoder.Encode(stack_limit_address.address()));
ExternalReference real_stack_limit_address = ExternalReference real_stack_limit_address =
ExternalReference::address_of_real_stack_limit(isolate); ExternalReference::address_of_real_stack_limit(isolate);
CHECK_EQ(make_code(UNCLASSIFIED, 5), CHECK_EQ(make_code(UNCLASSIFIED, 3),
encoder.Encode(real_stack_limit_address.address())); encoder.Encode(real_stack_limit_address.address()));
CHECK_EQ(make_code(UNCLASSIFIED, 16), CHECK_EQ(make_code(UNCLASSIFIED, 8),
encoder.Encode(ExternalReference::debug_break(isolate).address())); encoder.Encode(ExternalReference::debug_break(isolate).address()));
CHECK_EQ(make_code(UNCLASSIFIED, 10), CHECK_EQ(
encoder.Encode( make_code(UNCLASSIFIED, 4),
ExternalReference::new_space_start(isolate).address())); encoder.Encode(ExternalReference::new_space_start(isolate).address()));
CHECK_EQ(make_code(UNCLASSIFIED, 3), CHECK_EQ(
encoder.Encode( make_code(UNCLASSIFIED, 1),
ExternalReference::roots_array_start(isolate).address())); encoder.Encode(ExternalReference::roots_array_start(isolate).address()));
CHECK_EQ(make_code(UNCLASSIFIED, 52), CHECK_EQ(make_code(UNCLASSIFIED, 34),
encoder.Encode(ExternalReference::cpu_features().address())); encoder.Encode(ExternalReference::cpu_features().address()));
} }
...@@ -153,13 +153,13 @@ TEST(ExternalReferenceDecoder) { ...@@ -153,13 +153,13 @@ TEST(ExternalReferenceDecoder) {
make_code(STATS_COUNTER, make_code(STATS_COUNTER,
Counters::k_total_compile_size))); Counters::k_total_compile_size)));
CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(), CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 4))); decoder.Decode(make_code(UNCLASSIFIED, 2)));
CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(), CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 5))); decoder.Decode(make_code(UNCLASSIFIED, 3)));
CHECK_EQ(ExternalReference::debug_break(isolate).address(), CHECK_EQ(ExternalReference::debug_break(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 16))); decoder.Decode(make_code(UNCLASSIFIED, 8)));
CHECK_EQ(ExternalReference::new_space_start(isolate).address(), CHECK_EQ(ExternalReference::new_space_start(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 10))); decoder.Decode(make_code(UNCLASSIFIED, 4)));
} }
......
#!/usr/bin/env python
# Copyright 2014 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import re
import os
import sys
DECLARE_FILE = "src/assembler.h"
REGISTER_FILE = "src/serialize.cc"
DECLARE_RE = re.compile("\s*static ExternalReference ([^(]+)\(")
REGISTER_RE = re.compile("\s*Add\(ExternalReference::([^(]+)\(")
WORKSPACE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), ".."))
# Ignore those.
BLACKLISTED = [
"page_flags",
"math_exp_constants",
"math_exp_log_table",
"ForDeoptEntry",
]
def Find(filename, re):
references = []
with open(filename, "r") as f:
for line in f:
match = re.match(line)
if match:
references.append(match.group(1))
return references
def Main():
declarations = Find(DECLARE_FILE, DECLARE_RE)
registrations = Find(REGISTER_FILE, REGISTER_RE)
difference = list(set(declarations) - set(registrations) - set(BLACKLISTED))
for reference in difference:
print("Declared but not registered: ExternalReference::%s" % reference)
return len(difference) > 0
if __name__ == "__main__":
sys.exit(Main())
...@@ -423,6 +423,12 @@ def CheckGeneratedRuntimeTests(workspace): ...@@ -423,6 +423,12 @@ def CheckGeneratedRuntimeTests(workspace):
return code == 0 return code == 0
def CheckExternalReferenceRegistration(workspace):
code = subprocess.call(
[sys.executable, join(workspace, "tools", "external-reference-check.py")])
return code == 0
def GetOptions(): def GetOptions():
result = optparse.OptionParser() result = optparse.OptionParser()
result.add_option('--no-lint', help="Do not run cpplint", default=False, result.add_option('--no-lint', help="Do not run cpplint", default=False,
...@@ -442,6 +448,7 @@ def Main(): ...@@ -442,6 +448,7 @@ def Main():
"two empty lines between declarations check..." "two empty lines between declarations check..."
success = SourceProcessor().Run(workspace) and success success = SourceProcessor().Run(workspace) and success
success = CheckGeneratedRuntimeTests(workspace) and success success = CheckGeneratedRuntimeTests(workspace) and success
success = CheckExternalReferenceRegistration(workspace) and success
if success: if success:
return 0 return 0
else: else:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment